【问题标题】:How to sort a queryset of different models in Wagtail/Django?如何在 Wagtail/Django 中对不同模型的查询集进行排序?
【发布时间】:2020-05-18 08:41:39
【问题描述】:

我有一个 Wagtail 网站,我正在为几种不同的页面类型/内容类型制作一个列表页面。我先按一个 sn-p 字段过滤:

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')

在 Wagtail 中,所有内容类型都继承自 Page 基类,这使得创建包含我想要的所有内容类型的查询集变得非常容易。但我不知道如何很好地排序。

last_published_at 排序适用于NewsPageContentPage,但不适用于Event,我想按DateTimeField 对事件进行排序。

我曾考虑在所有名为 sort_date 的模型上创建一个 @property,它使用特定于我想要排序的每个模型的日期时间字段,但这不起作用。

非常欢迎任何建议!

【问题讨论】:

  • 你是如何设置你的 models.py 的?
  • 你能说得更具体点吗?我将所有内容类型设置为子类wagtail.core.models.Page,因此它们都可以通过ForeignKeylast_published_at 用作字段。
  • 我明白你的意思,但我想问你是否愿意以任何你喜欢的方式发布你的相关 models.py 代码,拜托。例如,我想知道 Event 和 NewsPage 是否是 Content Page 的子类。
  • 感谢您的澄清。它们都继承自Page。我已将它们放在 Dpaste 中,但如果长期而言更好的话,可以编辑问题 - dpaste.org/DLTW

标签: python django wagtail


【解决方案1】:

我可以为此想到两种解决方案,但似乎只有一种更容易做到。我把你上面的函数改成这样:

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
    )

它的作用是从highlights 获取所有页面,并根据datelast_published_at 中的值对它们进行排序,就好像它们是同一个字段一样。因为只有Event 页面有一个date 字段,所以last_published_at 被用作后备,所有活动页面都有一个字段。如果您像问题一样在查询集中遗漏specific(),它会抛出AttributeError'Page' object has no attribute 'date'

作为奖励,排序部分不使用任何数据库查询,因为它是在 Python 中完成的。请注意,这会返回一个基于原始QuerySet 的列表。

第二个解决方案涉及数据库事务和 Wagtail 钩子,代码更多,但我不想分享,因为我还没有想到如何写出来。

【讨论】:

  • 这几乎是完美的。我实际上需要将lambda 更改为key=lambda p: getattr(p, 'date', None) or getattr(p, 'last_published_at') 以避免异常。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-12-20
  • 2011-11-11
  • 2023-02-02
  • 1970-01-01
  • 2020-10-24
  • 2021-11-30
  • 2014-07-30
  • 2021-10-01
相关资源
最近更新 更多