Django ModelAdmin的queryset覆盖不起作用

4

我正在尝试覆盖ModelAdmin类中的queryset()函数,以便在管理界面中显示的对象列表按照两个级别排序。

我尝试了以下代码,但它并不起作用,即表格未按预期排序。

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 明确说明只有排序元组中的第一个项目会生效(请参见文档中的注释此处)。

3个回答

8

get_queryset 用于 Django 1.8。


3
我曾经遇到过这个问题,我做了以下几步:
我继承了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')

此外,请检查以下这些票:


1
哇,这是一个三年前的工单,但仍被标记为“新”。在我看来,这似乎是一个设计缺陷... - Jonathan Livni
@Jonathan:同意,这是一个非常令人沮丧的错误。 - Tiago

1

Django 1.4的发布说明中提到,Django现在支持管理界面中的多重排序

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

并且从ModelAdmin ordering中得知:

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

半相关的是 - 如果您覆盖queryset以提供自定义排序顺序,则似乎Changelist将覆盖该排序顺序。它应用在ordering参数中找到的任何排序,如果没有排序,则应用默认排序pk,从而抵消了您在queryset中进行的任何排序。

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

请注意,可以通过代码进行自定义排序,但必须子类化Changelist并覆盖其get_query_set()方法,如this snippet所述。(尽管这是一种过度设计,如果您只需要多个字段排序,因为Django 1.4现在支持多个字段)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接