我使用的是Wagtail,我想用外键筛选所选的子页面。我尝试了以下操作,在尝试children = self.get_children().specific().filter(use_case__slug=slug)
时出现错误django.core.exceptions.FieldError: Cannot resolve keyword 'use_case' into field
:
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,
})
我已经看到了this answer,但这假设我只想筛选一种类型的页面。使用类似AiLabCaseStudy.objects.filter(use_case__slug=slug)
的方法是可行的,但这只返回AiLabCaseStudy
s,而不是AiLabBlogPost
s或AiLabExternalLink
s
有什么想法吗
在数据库级别,没有一种有效的方法可以一次针对所有页面类型运行筛选器。由于
AiLabResourceMixin
被定义为abstract = True
,因此该类在数据库中没有自己的表示形式-相反,为AiLabCaseStudy
、AiLabBlogPost
和AiLabExternalLink
分别定义了use_case
字段。因此,Django或Wagtail无法将.filter(use_case__slug=slug)
转换为SQL查询,因为use_case
引用数据库中的三个不同位置有几种可能的解决方法:
如果您的数据模型允许,请将其重新构造为使用multi-table inheritance-这看起来与您当前的定义非常相似,只是没有
abstract = True
:AiLabResourcePage
将以其自身的形式存在于数据库中,并且您可以使用如下表达式查询其use_case
字段:AiLabResourcePage.objects.child_of(self).filter(use_case__slug=slug).specific()
。这里会有一个小的性能影响,因为Django必须从一个额外的表中提取数据来构造这些页面对象在使用
specific()
运行最终查询之前,对每个特定页面类型运行初步查询以检索匹配的页面ID:尝试:
children = self.get_children().filter(use_case__slug=slug).specific()
相关问题 更多 >
编程相关推荐