Reputation: 604
I have a Wagtail site and I'm making a listing page for a few different Page types/Content types. 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. 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.
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.
Any suggestions are very welcome!
Upvotes: 0
Views: 1658
Reputation: 303
I can think of two solutions for this, but only one seems to be easier to do. I changed your function above to this:
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. 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. If you leave out specific()
in your queryset like in your question, it throws an AttributeError
saying '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
.
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.
Upvotes: 1