首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用ForeignKey过滤子页面

用ForeignKey过滤子页面
EN

Stack Overflow用户
提问于 2020-07-14 17:23:33
回答 2查看 609关注 0票数 1

我使用的是摇尾,我想通过一个外键过滤一个选择的子页面。我尝试了以下操作,当我尝试使用django.core.exceptions.FieldError: Cannot resolve keyword 'use_case' into field时,我得到了错误的children = self.get_children().specific().filter(use_case__slug=slug)

代码语言:javascript
复制
class AiLabResourceMixin(models.Model):
  parent_page_types = ['AiLabResourceIndexPage']
  use_case = models.ForeignKey(AiLabUseCase, on_delete=models.PROTECT)
  content_panels = ArticlePage.content_panels + [
    FieldPanel('use_case', widget=forms.Select())
  ]

  class Meta:
    abstract = True

class AiLabCaseStudy(AiLabResourceMixin, ArticlePage):
  pass

class AiLabBlogPost(AiLabResourceMixin, ArticlePage):
  pass

class AiLabExternalLink(AiLabResourceMixin, ArticlePage):
  pass

class AiLabResourceIndexPage(RoutablePageMixin, BasePage):
  parent_page_types = ['AiLabHomePage']
  subpage_types = ['AiLabCaseStudy', 'AiLabBlogPost', 'AiLabExternalLink']
  max_count = 1

  @route(r'^$')
  def all_resources(self, request):
    children = self.get_children().specific()

    return render(request, 'ai_lab/ai_lab_resource_index_page.html', {
      'page': self,
      'children': children,
    })

  @route(r'^([a-z0-9]+(?:-[a-z0-9]+)*)/$')
  def filter_by_use_case(self, request, slug):
    children = self.get_children().specific().filter(use_case__slug=slug)

    return render(request, 'ai_lab/ai_lab_resource_index_page.html', {
      'page': self,
      'children': children,
    })

我见过这个答案,但这假设我只想过滤一种类型的页面。使用类似于AiLabCaseStudy.objects.filter(use_case__slug=slug)的东西可以工作,但这只返回AiLabCaseStudys,而不是AiLabBlogPosts或AiLabExternalLinks。

有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-14 18:33:06

在数据库级别,没有一次对所有页面类型运行筛选器的有效方法。因为AiLabResourceMixin被定义为abstract = True,所以这个类在数据库中没有自己的表示-相反,use_case字段是为AiLabCaseStudyAiLabBlogPostAiLabExternalLink中的每个单独定义的。因此,Django或Wagtail无法将.filter(use_case__slug=slug)转换为SQL查询,因为use_case引用了数据库中的三个不同位置。

有几种可能的方法来解决这个问题:

  • 如果您的数据模型允许,那么重新构造它以使用多表继承 --这看起来非常类似于您当前的定义,除非没有abstract = True: 类AiLabResourcePage(ArticlePage):use_case = models.ForeignKey(AiLabUseCase,on_delete=models.PROTECT)类AiLabCaseStudy(AiLabResourcePage):pass class AiLabBlogPost(AiLabResourcePage):pass class AiLabExternalLink(AiLabResourcePage):pass 然后,AiLabResourcePage将独立存在于数据库中,您可以使用类似于:AiLabResourcePage.objects.child_of(self).filter(use_case__slug=slug).specific()的表达式查询它的use_case字段。这里的性能影响很小,因为Django必须从一个额外的表中提取数据来构造这些页面对象。
  • 在使用specific()运行最终查询之前,对每个特定页面类型运行一个初步查询以检索匹配的页ID: ( list(AiLabCaseStudy.objects.child_of(self).filter(use_case__slug=slug).values_list('id',)( case_study_ids =flat=True)( blog_post_ids = flat=True)) ( external_link_ids = list(AiLabExternalLink.objects.child_of(self).filter(use_case__slug=slug).values_list('id',(flat=True)儿童= Page.objects.filter(id__in=(case_study_ids + blog_post_ids + external_link_ids)).specific()
票数 2
EN

Stack Overflow用户

发布于 2020-07-14 17:32:51

尝试:

children = self.get_children().filter(use_case__slug=slug).specific()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62900674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档