Django ModelAdmin queryset override doesn't work
I'm trying to override the queryset() of a ModelAdmin class so that the list of objects shown in admin would be sorted by two levels.
I've tried the following code, but it does not work, i.e. the table is not sorted as expected开发者_运维问答
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)
btw, you can't use ordering = ('category','market')
as django specifically states that only the first item in the ordering tuple takes effect (see note in the documentation here)
get_queryset
works in Django 1.8.
I had this exactly problem. Here's what I did:
I subclassed ChangeList
and overrode ChangeList.get_query_set
to redo the correct order_by that was previously changed by ChangeList.get_ordering
:
This is what I did in my case (I'm using django-easytree, but the same applies for django-mptt):
class MyChangeList(ChangeList):
def get_query_set(self):
qs = super(MyChangeList, self).get_query_set()
return qs.order_by('tree_id', 'lft')
Also, check these tickets:
"NFA: Don't override order_by if no default ordering is specified"
"Admin ChangeList doesn't apply 'order_by' clause specified by ModelAdmin.queryset"
The release notes for Django 1.4 say that Django now supports Multiple sort in admin interface
:
The admin change list now supports sorting on multiple columns. It respects all elements of the ordering attribute, and sorting on multiple columns by clicking on headers is designed to mimic the behavior of desktop GUIs.
And from ModelAdmin ordering:
Set
ordering
to specify how lists of objects should be ordered in the Django admin views. This should be a list or tuple in the same format as a model'sordering
parameter. [...] Django honors all elements in the list/tuple; before 1.4, only the first was respected.
On a semi-related note - if you do override queryset
to provide a custom sort order, it seems that the Changelist
will override that sort order. It applies any sorting found in the ordering
parameter, and if there isn't one, it applies a default sort by pk
, thus negating any sorting you did in queryset
.
I think it's supposed to work - at least this Django Ticket says fixed. But I was just trying to apply a custom sort using queryset
a few days ago, and it didn't work at all for me. Even sorting on a single field, seemed to be overridden in the final view. So either I did something wrong, or it's not all that fixed. :)
Note that it is possible to do a custom sort via code, but you have to subclass Changelist
, and override its get_query_set()
method, as per this snippet. (Although this is overkill, if you only need multiple fields sorted, since Django 1.4 now supports multiple fields).
精彩评论