Django ModelAdmin 查询集覆盖不起作用

Posted

技术标签:

【中文标题】Django ModelAdmin 查询集覆盖不起作用【英文标题】:Django ModelAdmin queryset override doesn't work 【发布时间】:2011-06-18 20:31:04 【问题描述】:

我正在尝试覆盖 ModelAdmin 类的 queryset(),以便 admin 中显示的对象列表按两个级别排序。

我试过下面的代码,但它不起作用,即表格没有按预期排序

class ProductAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(ProductAdmin, self).queryset(request)
        return qs.order_by('category','market')

    list_display = ('category', 'market', 'name', 'quantity')

admin.site.register(Product, ProductAdmin)

顺便说一句,您不能使用ordering = ('category','market'),因为 django 明确指出只有排序元组中的第一项生效(请参阅文档中的注释here)

【问题讨论】:

【参考方案1】:

我遇到了这个问题。这是我所做的:

我继承了ChangeList 并覆盖了ChangeList.get_query_set 以重做之前由ChangeList.get_ordering 更改的正确order_by:

这就是我在我的案例中所做的(我使用的是 django-easytree,但同样适用于 django-mptt):

class MyChangeList(ChangeList):

    def get_query_set(self):
        qs = super(MyChangeList, self).get_query_set()

        return qs.order_by('tree_id', 'lft')

另外,请检查这些票:

"NFA: Don't override order_by if no default ordering is specified"

"Admin ChangeList doesn't apply 'order_by' clause specified by ModelAdmin.queryset"

【讨论】:

哇,这是一张 3 年前的票,仍然标记为“新”。对我来说似乎是一个设计错误...... @Jonathan:同意了,这是一个非常令人沮丧的错误。【参考方案2】:

Django 1.4 的 release notes 表示 Django 现在支持 Multiple sort in admin interface

管理员更改列表现在支持对多列进行排序。它 尊重 ordering 属性的所有元素,并排序 通过单击标题的多个列旨在模仿 桌面 GUI 的行为。

来自ModelAdmin ordering:

设置ordering 指定对象列表在 Django 管理员视图。这应该是相同格式的列表或元组 作为模型的ordering 参数。 [...] Django 尊重列表/元组中的所有元素;在 1.4 之前,只尊重第一个。

在一个半相关的注释上 - 如果您确实覆盖 queryset 以提供自定义排序顺序,似乎 Changelist 将覆盖该排序顺序。它应用在ordering 参数中找到的任何排序,如果没有,它会应用pk 的默认排序,从而否定您在queryset 中所做的任何排序。

认为它应该可以工作 - 至少这个Django Ticket 说已修复。但是几天前我只是尝试使用queryset 应用自定义排序,这对我来说根本不起作用。即使在单个字段上进行排序,在最终视图中似乎也被覆盖了。所以要么我做错了什么,要么它不是完全固定的。 :)

请注意,可以通过代码进行自定义排序,但您必须继承 Changelist,并按照 this snippet 覆盖其 get_query_set() 方法。 (虽然这有点矫枉过正,如果你只需要对多个字段进行排序,因为 Django 1.4 现在支持多个字段)。

【讨论】:

【参考方案3】:

get_queryset 在 Django 1.8 中工作。

【讨论】:

以上是关于Django ModelAdmin 查询集覆盖不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在 django 中测试 admin.ModelAdmin

如何覆盖 Django 的 ModelAdmin 的“媒体”属性并使其动态化?

Django ModelAdmin - 字段集...表单中缺少字段“日期”

覆盖 Django admin 中的默认查询集

在生成 django 管理 URL 时覆盖查询集过滤器

django - 内部连接查询集不起作用