Администратор Django: порядок второго уровня в list_display - PullRequest
2 голосов
/ 30 декабря 2010

Показывая модель в list_display администратора Django, я хотел бы отсортировать сначала по одному столбцу, а затем по другому.
Вот пример модели:

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

Как этого достичь?

Ответы [ 3 ]

1 голос
/ 31 декабря 2010

Я думаю, что вы ищете атрибут "ordering" административного класса.

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

Редактировать: мой предыдущий ответ неверен. Согласно документации выше, Django только чтит первую запись в кортеже. Существует / был билет , чтобы решить эту проблему, которая ни к чему не привела. Существуют и другие предлагаемые решения, которые я также попробовал, но ни одно из них, похоже, не работало с моей версией Django.

Однако сегодня я вернулся к этой проблеме в рамках проекта и наконец нашел то, что мне помогло. Мое решение было основано на этом фрагменте Django , и я приведу здесь фрагмент кода для полноты.

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)
0 голосов
/ 11 октября 2011

Этого можно добиться, используя ствол Django, а не 1,3

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

Новое в версии Django Development.

Если вам нужно указатьдинамический порядок (например, в зависимости от пользователя или языка) вы можете реализовать метод get_ordering ().

Изменено в версии Django Development.

Django учитывает все элементы в списке / кортеже;до 1.4 уважалось только первое.

0 голосов
/ 11 октября 2011

Это основано на отредактированном ответе bogeyman 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, но в конечном итоге выведите набор_просетовотсортировано по порядку, указанному в мета-модели.

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.

...