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 的 ModelAdmin 的“媒体”属性并使其动态化?