Почему я не могу зарегистрировать несколько Django ModelAdmin с той же моделью?

133
16

У меня есть следующий ModelAdmin:


class EventAdmin(admin.ModelAdmin):
# ModelAdmin config

def queryset(self, request):
queryset = super(EventAdmin, self).queryset(request)
return queryset.exclude(date_end__lt=date.today())

admin.site.register(Event, EventAdmin)


Теперь я хочу добавить модель для управления архивированными (старше, чем сегодня) событиями.


class EventArchiveAdmin(admin.ModelAdmin):
# ModelAdmin config

def queryset(self, request):
queryset = super(EventArchiveAdmin, self).queryset(request)
return queryset.filter(date_end__lt=date.today())

admin.site.register(Event, EventArchiveAdmin)


Но если я попытаюсь сделать это, я получаю исключение AlreadyRegistered.


Почему я не могу реализовать другой ModelAdmin с той же моделью и как я могу получить разные представления администратора одной модели?


Я знаю, что могу реализовать пользовательский list_filter в своем классе, но я бы хотел, чтобы вещи были разделены на разных страницах.

спросил(а) 2021-01-25T21:14:01+03:00 4 месяца, 4 недели назад
1
Решение
192

Использовать модели прокси:


class Event(db.Model):
...

class ActiveEventManager(models.Manager):
def get_queryset(self):
return super(ActiveEventManager, self).get_queryset().filter(active=True)

class ActiveEvent(Event):
class Meta:
proxy = True

objects = ActiveEventManager()

class ArchiveEventManager(models.Manager):
def get_queryset(self):
return super(ArchiveEventManager, self).get_queryset().filter(active=False)

class ArchiveEvent(Event):
class Meta:
proxy = True

objects = ArchiveEventManager()


Теперь вы можете зарегистрировать 2 модели без переопределения метода ModelAdmin.queryset:


class EventAdmin(admin.ModelAdmin):
# ModelAdmin config

admin.site.register(ActiveEvent, EventAdmin)
admin.site.register(ArchiveEvent, EventAdmin)


Вы можете прочитать режим прокси-модели и managers в документе.

Кроме того, используйте это:


queryset = super(EventArchiveAdmin, self).queryset(request)

В качестве первого аргумента super() возьмем текущий класс. См. doc


Примечание: django переименовал Manager.get_query_set в Manager.get_queryset в django == 1.7.

ответил(а) 2021-01-25T21:14:01+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема