python - 鹡鸰中的类别无法解析

标签 python django content-management-system wagtail

我在这里做错了什么?因为我不断收到无法将关键字类别解析为字段错误的信息。

该行抛出异常

services = services.filter(categories__category__name=category)

但是,查看代码,我们会发现 service_categories 字段和 ServiceCategory 之间通过 ServiceCategoryServicePage 建立了关系,相关名称为“categories”。所以我想不应该抛出无法解析字段的异常错误。此时任何帮助将不胜感激。

def get_service_context(context):
    context['all_categories'] = ServiceCategory.objects.all()
    context['root_categories'] = ServiceCategory.objects.filter(
    parent=None,
    ).prefetch_related(
    'children',
    ).annotate(
    service_count=Count('servicepage'),
    )
    return context

class ServiceIndexPage(Page):
    header_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    heading = models.CharField(max_length=500, null=True, blank=True)
    sub_heading = models.CharField(max_length=500, null=True, blank=True)
    body = RichTextField(null=True, blank=True)

    def get_context(self, request, category=None, *args, **kwargs):
        context = super(ServiceIndexPage, self).get_context(request, *args, **kwargs)

        services = self.get_children().live().order_by('-first_published_at') #.prefetch_related('categories', 'categories__category')

        if category is None:
            if request.GET.get('category'):
                category = get_object_or_404(ServiceCategory, slug=request.GET.get('category'))
        if category:
            if not request.GET.get('category'):
                category = get_object_or_404(ServiceCategory, slug=category)
            services = services.filter(categories__category__name=category)

        # Pagination
        page = request.GET.get('page')
        page_size = 10
        if hasattr(settings, 'SERVICE_PAGINATION_PER_PAGE'):
        page_size = settings.SERVICE_PAGINATION_PER_PAGE

        if page_size is not None:
            paginator = Paginator(services, page_size)  # Show 10 services per page
            try:
                services = paginator.page(page)
            except PageNotAnInteger:
                services = paginator.page(1)
            except EmptyPage:
                services = paginator.page(paginator.num_pages)


        context['services'] = services
        context['category'] = category
        context = get_service_context(context)

        return context


@register_snippet
class ServiceCategory(models.Model):
    name = models.CharField(max_length=250, unique=True, verbose_name=_('Category Name'))
    slug = models.SlugField(unique=True, max_length=250)
    parent = models.ForeignKey('self', blank=True, null=True, related_name="children")
    date = models.DateField(auto_now_add=True, auto_now=False, null=True, blank=True)
    description = RichTextField(blank=True)

    class Meta:
        ordering = ['-date']
        verbose_name = _("Service Category")
        verbose_name_plural = _("Service 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:
            slug = slugify(self.name)
            count = ServiceCategory.objects.filter(slug=slug).count()
            if count > 0:
                slug = '{}-{}'.format(slug, count)
            self.slug = slug
        return super(ServiceCategory, self).save(*args, **kwargs)

class ServiceCategoryServicePage(models.Model):
    category = models.ForeignKey(ServiceCategory, related_name="+", verbose_name=_('Category'))
    page = ParentalKey('ServicePage', related_name='categories')
    panels = [
        FieldPanel('category'),
    ]



class ServicePage(Page):
    header_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Header image')
    )
    service_title = models.CharField(max_length=300, null=True, blank=True)
    body = StreamField([
        ('h1', CharBlock(icon="title", classanme="title")),
        ('h2', CharBlock(icon="title", classanme="title")),
        ('h3', CharBlock(icon="title", classanme="title")),
        ('h4', CharBlock(icon="title", classanme="title")),
        ('h5', CharBlock(icon="title", classanme="title")),
        ('h6', CharBlock(icon="title", classanme="title")),
        ('paragraph', RichTextBlock(icon="pilcrow")),
        ('aligned_image', ImageBlock(label="Aligned image", icon="image")),
        ('pullquote', PullQuoteBlock()),
        ('raw_html', RawHTMLBlock(label='Raw HTML', icon="code")),
        ('embed', EmbedBlock(icon="code")),
    ])
    date = models.DateField("Post date")
    service_categories = models.ManyToManyField(ServiceCategory, through=ServiceCategoryServicePage, blank=True)

    feed_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=_('Feed image')
    )

    search_fields = Page.search_fields + [
        index.SearchField('body'),
        index.SearchField('service_title'),
        index.SearchField('title'),]


    def get_absolute_url(self):
        return self.url


    def get_service_index(self):
        # Find closest ancestor which is a service index
        return self.get_ancestors().type(ServiceIndexPage).last()


    def get_context(self, request, *args, **kwargs):
        context = super(ServicePage, self).get_context(request, *args, **kwargs)
        context['services'] = self.get_service_index().serviceindexpage
        context = get_service_context(context)
        return context

    class Meta:
        verbose_name = _('Service page')
        verbose_name_plural = _('Services pages')

    parent_page_types = ['services.ServiceIndexPage']


ServicePage.content_panels = [
    FieldPanel('title', classname="full title"),
    FieldPanel('service_title'),
    ImageChooserPanel('header_image'),
    FieldPanel('date'),
    InlinePanel('categories', label=_("Categories")),
    StreamFieldPanel('body'),
    ImageChooserPanel('feed_image'),
]

最佳答案

当你在线调用self.get_children()时:

services = self.get_children().live().order_by('-first_published_at')

结果是 Page 对象的查询集,其中仅包含所有页面类型通用的基本字段,例如 title - 因此,无法过滤此字段基于类别的查询集。发生这种情况是因为 Wagtail 无法知道 ServiceIndexPage 的子页面都是 ServicePage - 请参阅 https://stackoverflow.com/a/46530443/1853523以获得更完整的解释。

但是,您可以按如下方式重写此行:

services = ServicePage.objects.child_of(self).live().order_by('-first_published_at')

我们可以确定查询集 ServicePage.objects.child_of(self) 将仅包含 ServicePage 对象,因此应该对 categories 进行过滤现在工作。

关于python - 鹡鸰中的类别无法解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46771611/

相关文章:

python - Pandas 滚动应用缺失数据

python mechanize.Browser 返回

python - 在 Python 中查找 `n` 正数加起来等于 `k` 的所有组合?

django - 仅在 Django 中测试项目

html - 如何让我的 iframe 代码在 django cms 中正确显示?

php - 像cms一样在.php文档中显示不同的mysql数据

python - 设计模式在 Web 开发中有多重要?

python - Django url 参数

python - Django + uwsgi + nginx + CentOS 7 : connection refused on 8001 port

html - 内容管理通讯/电子杂志?