通过 Meta 订购自定义模型实例?

Custom model instance ordering via Meta?

我无法为我的页面模型实例获取自定义默认排序。它们总是按 pk 升序排列。

这会导致不直观的下拉菜单、选择器(例如 CheckboxSelectMultiple)等;特别是当有很多 items/instances.

用例:一个 AuthorPage 和一个 PublicationPage 模型:

class AuthorPage(Page):
    first_name = CharField(max_length=255)
    last_name = CharField(max_length=255)

    class Meta:
        ordering = ['last_name', 'first_name']

class ArticlePage(Page):
    authors = ParentalManyToManyField('AuthorPage',)
    content_panels = Page.content_panels + [
        FieldPanel('authors', widget=CheckboxSelectMultiple),
    ]

我喜欢 CheckboxSelectMultiple 尊重相关模型的元排序,这里 AuthorPage 并显示按字母顺序排列的作者列表。但是,相反,我得到的是按作者实例的 pk 排序的列表。 AuthorPage class 上的 ordering 似乎不是 evaluated/used.

在检查默认 AuthorPage 查询集 (AuthorPage.objects.all()) 时,作者的下拉列表和 python shell 中出现了相同的(不需要的)排序。

如何让 wagtail 按自定义标准(不是 pk)对我的页面模型实例进行排序?


设置:

您假设 Wagtail 页面顺序是 pk 是错误的。 Wagtail 按路径排序页面(Wagtail 使用 django-treebeard)。这启用了用户定义的排序。首先单击顺序符号(第一列),然后拖放页面。

文档是这样说的:

Page-derived models cannot be given a default ordering by using the standard Django approach of adding an ordering attribute to the internal Meta class.

This is because Page enforces ordering QuerySets by path. Instead, you must apply the ordering explicitly when constructing a QuerySet:

news_items = NewsItemPage.objects.live().order_by('-publication_date')

文档:https://docs.wagtail.io/en/v2.3/topics/pages.html#page-queryset-ordering

您能否尝试自己定义选项以及顺序?这样的事情可能会奏效:

FieldPanel(
    'authors', 
    widget=CheckboxSelectMultiple(
        choices=ProfilePage.objects.all().order_by('title').values_list('pk', 'title')
    )
),

另一种可能性是扩展和更改此模型 class 的默认值 PageManager(再次感谢@allcaps):

class ProfilePageManager(PageManager):
    def get_queryset(self):
        return super().get_queryset().order_by('last_name', 'first_name')

class ProfilePage(Page):
    objects = ProfilePageManager()

默认页面管理器 return 是一个带有 order_by('path') [1] 的查询集,所以我将其更改为 return 一个按我的自定义条件排序的查询集:order_by('last_name', 'first_name').

现在,小部件(例如 CheckboxSelectMultiple)、下拉菜单等在整个站点中接收此有序查询集作为 options/choices,无需修改其现有实例。

[1] https://github.com/wagtail/wagtail/blob/master/wagtail/core/models.py#L191