简体   繁体   English

如何在 Wagtail/Django 中对不同模型的查询集进行排序?

[英]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排序适用于NewsPageContentPage但不适用于我想按EventDateTimeField排序的事件。

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中获取所有页面,并根据datelast_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM