Django admin:list_display中的二级排序

时间:2010-12-30 07:44:29

标签: sorting django-models django-admin

在Django admin list_display中显示模型时,我想首先按一列排序,然后按另一列排序。
这是一个示例模型:

class Customer(models.Model):
    name  = models.CharField(max_length=30)
    the_date = models.DateField()

如何实现这一目标?

3 个答案:

答案 0 :(得分:1)

我认为您正在寻找管理类的“排序”属性。

http://docs.djangoproject.com/en/1.3/ref/contrib/admin/

编辑:我之前的回答不正确。根据上面的文档,Django只尊重元组中的第一个条目。有a ticket解决这个问题无处可去。我还尝试过各种其他提议的解决方案,但它们似乎都不适用于我的Django版本。

然而,我今天作为项目的一部分回到了这个问题,终于找到了对我有用的东西。我的解决方案基于this Django snippet,我将在此处发布代码段代码以便完整。

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList
from tunes.models import Song

class SpecialOrderingChangeList(ChangeList):
    def apply_special_ordering(self, queryset):
        order_type, order_by = [self.params.get(param, None) for param in ('ot', 'o')]
        special_ordering = self.model_admin.special_ordering
        if special_ordering and order_type and order_by:
            try:
                order_field = self.list_display[int(order_by)]
                ordering = special_ordering[order_field]
                if order_type == 'desc':
                    ordering = ['-' + field for field in ordering]
                queryset = queryset.order_by(*ordering)
            except IndexError:
                return queryset
            except KeyError:
                return queryset
        return queryset

    def get_query_set(self):
        queryset = super(SpecialOrderingChangeList, self).get_query_set()
        queryset = self.apply_special_ordering(queryset)
        return queryset

class SongAdmin(admin.ModelAdmin):
    list_display = ['name', 'time', 'artist', 'album', 'track', 'total_tracks']
    special_ordering = {'artist': ('artist', 'album', 'track'), 'album': ('album', 'track')}

    def get_changelist(self, request, **kwargs):
        return SpecialOrderingChangeList

admin.site.register(Song, SongAdmin)

答案 1 :(得分:0)

这是基于bogeyman 4月1日编辑的答案,但细分为基本功能。

在我的models.py中照常定义ordering模型Meta

class Customer(models.Model):
    name  = models.CharField(max_length=30)
    the_date = models.DateField()

    class Meta:
        ordering = ('the_date', 'name') # sort by date then name.

然后在admin.py子类ChangeList中,但强制query_set最终按照模型Meta中指定的顺序排序。

from django.contrib import admin
from django.contrib.admin.views.main import ChangeList


class SpecialOrderingChangeList(ChangeList):
    def get_query_set(self):
        queryset = super(SpecialOrderingChangeList, self).get_query_set()
        return queryset.order_by(*self.model._meta.ordering)

class CustomerAdmin(admin.ModelAdmin):
    def get_changelist(self, request, **kwargs):
        return SpecialOrderingChangeList

admin.site.register(Customer, CustomerAdmin)

如果您更愿意在ModelAdmin中定义排序;你也可以这样做;只需将return queryset.order_by(*self.model._meta.ordering)更改为return queryset.order_by(*self.model_admin.ordering),然后在ordering = ['the_date', 'name']中添加定义CustomerAdmin的列表。

答案 2 :(得分:0)

你可以通过使用Django trunk而不是1.3

来实现这一点

https://docs.djangoproject.com/en/dev/ref/contrib/admin/

  

Django Development版本的新功能。

     

如果需要指定动态   你可以实现一个命令(例如,取决于用户或语言)   get_ordering()方法。

     

更改了Django Development版本。

     

Django尊重所有元素   列表/元组;在1.4之前,只有第一个受到尊重。