[英]How to sort a queryset of different models in Wagtail/Django?
I have a Wagtail site and I'm making a listing page for a few different Page types/Content types.我有一个 Wagtail 网站,我正在为几种不同的页面类型/内容类型制作一个列表页面。 I filter by a snippet field first:
我首先按片段字段进行过滤:
def highlights_list(category='Highlight'):
tag = ContentCategory.objects.get(name=category)
highlights = Page.objects.filter(
Q(event__categories=tag)|
Q(newspage__categories=tag)|
Q(contentpage__categories=tag)).live()
return highlights.order_by('-last_published_at')
In Wagtail all content types inherit from the base Page
class which makes creating a queryset with all the content types I want really easy.在 Wagtail 中,所有内容类型都继承自基础
Page
class,这使得创建包含我想要的所有内容类型的查询集变得非常容易。 But I can't work out how to sort nicely.但我不知道如何很好地排序。
Sorting by last_published_at
is fine for NewsPage
and ContentPage
but not for Event
where I'd like to sort by the DateTimeField
for the event.按
last_published_at
排序适用于NewsPage
和ContentPage
但不适用于我想按Event
的DateTimeField
排序的事件。
I thought about making a @property
on all the models called sort_date
which uses the datetime field specific to each model that I'd like to sort on, but that just doesn't work.我考虑过在所有名为
@property
的模型上创建一个sort_date
,它使用特定于我想要排序的每个 model 的日期时间字段,但这行不通。
Any suggestions are very welcome!非常欢迎任何建议!
I can think of two solutions for this, but only one seems to be easier to do.我可以想到两种解决方案,但似乎只有一种更容易实现。 I changed your function above to this:
我将上面的 function 更改为:
def highlights_list(category='Highlight'):
tag = ContentCategory.objects.get(name=category)
highlights = Page.objects.filter(
Q(event__categories=tag)|
Q(newspage__categories=tag)|
Q(contentpage__categories=tag)
).live().specific()
return sorted(
highlights,
key=lambda p: getattr(p, 'date') or getattr(p, 'last_published_at'),
reverse=True
)
What this does is it takes all the pages from highlights
and sorts them based on the value in date
or last_published_at
as if they're the same field.它所做的是从
highlights
中获取所有页面,并根据date
或last_published_at
中的值对它们进行排序,就好像它们是同一字段一样。 Because only the Event
page has a date
field, last_published_at
is used as the fallback, a field all live pages have in common.因为只有
Event
页面有date
字段, last_published_at
用作后备,这是所有活动页面共有的字段。 If you leave out specific()
in your queryset like in your question, it throws an AttributeError
saying 'Page' object has no attribute 'date'
.如果您像在问题中那样在查询集中遗漏了
specific()
,它会抛出一个AttributeError
说'Page' object has no attribute 'date'
。
As a bonus, the sorting part doesn't use any database queries since it is done in Python. Note that this returns a list based on the original QuerySet
.作为奖励,排序部分不使用任何数据库查询,因为它是在 Python 中完成的。请注意,这会返回一个基于原始
QuerySet
的列表。
The second solution involves database transactions and Wagtail hooks and has more code, but that is something I don't want to share as I haven't thought of how to write that out.第二个解决方案涉及数据库事务和 Wagtail 挂钩,并且有更多代码,但这是我不想分享的东西,因为我还没有想到如何写出来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.