Nested categories/InlinePanel(s) in wagtail

前端 未结 1 881
梦谈多话
梦谈多话 2021-02-06 11:54

I struggle to implement something like \"nested categories\":

PageA:
  - Cat1
    - SubCat1
    - SubCat2
    - ...
  - Cat2
    - SubCat1
  - ...
相关标签:
1条回答
  • 2021-02-06 12:48

    Here's one way to do it, with much room for interface improvements ;) In order to sort the categories at the page level, I'd suggest the use of django-sortedm2m.

    from wagtail.wagtailcore.models import Orderable, Page
    from wagtail.wagtailsnippets.models import register_snippet
    from django.db import models
    
    
    @register_snippet
    class Category(models.Model):
        name = models.CharField(
            max_length=80, unique=True, verbose_name=_('Category Name'))
        slug = models.SlugField(unique=True, max_length=80)
        parent = models.ForeignKey(
            'self', blank=True, null=True, related_name="children",
            help_text=_(
                'Categories, unlike tags, can have a hierarchy. You might have a '
                'Jazz category, and under that have children categories for Bebop'
                ' and Big Band. Totally optional.')
        )
        description = models.CharField(max_length=500, blank=True)
    
        class Meta:
            ordering = ['name']
            verbose_name = _("Category")
            verbose_name_plural = _("Categories")
    
        panels = [
            FieldPanel('name'),
            FieldPanel('parent'),
            FieldPanel('description'),
        ]
    
        def __str__(self):
            return self.name
    
        def clean(self):
            if self.parent:
                parent = self.parent
                if self.parent == self:
                    raise ValidationError('Parent category cannot be self.')
                if parent.parent and parent.parent == self:
                    raise ValidationError('Cannot have circular Parents.')
    
        def save(self, *args, **kwargs):
            if not self.slug:
                self.slug = slugify(self.name)
            return super(Category, self).save(*args, **kwargs)
    
    
    class CategoryPage(models.Model):
        category = ParentalKey('Category', related_name="+", verbose_name=_('Category'))
        page = ParentalKey('MyPage', related_name='+')
        panels = [
            FieldPanel('category'),
        ]
    
    
    class MyPage(Page):
        categories = models.ManyToManyField(Category, through=CategoryPage, blank=True)
        content_panels = Page.content_panels + [
            FieldPanel('categories'),
        ]
    
    0 讨论(0)
提交回复
热议问题