Несколько ModelAdmins / представлений для одной модели в Django admin

как я могу создать более одного ModelAdmin для одной и той же модели, каждый из которых настроен по-разному и связан с разными URL-адресами?

предположим, у меня есть модель Django под названием Posts. По умолчанию в представлении администратора этой модели будут перечислены все объекты Post.

Я знаю, что могу настроить список объектов, отображаемых на странице различными способами, установив переменные, такие как list_display или переопределив queryset метод в моем ModelAdmin так:

class MyPostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date')

    def queryset(self, request):
        request_user = request.user
        return Post.objects.filter(author=request_user)

admin.site.register(MyPostAdmin, Post)

By по умолчанию, это будет доступно по URL /admin/myapp/post. Однако я хотел бы иметь несколько представлений/ModelAdmins одной и той же модели. е.г /admin/myapp/post перечислит все объекты post и /admin/myapp/myposts будет список всех сообщений, принадлежащих пользователю, и /admin/myapp/draftpost может перечислить все посты, которые еще не были опубликованы. (это всего лишь примеры, мой фактический прецедент более сложен)

вы не можете зарегистрировать более одного ModelAdmin для одной модели (это приводит к AlreadyRegistered исключения). В идеале я хотел бы для достижения этого без поместите все в один класс ModelAdmin и напишите мою собственную функцию "urls", чтобы вернуть другой набор запросов в зависимости от URL.

Я посмотрел на источник Django, и я вижу такие функции, как ModelAdmin.changelist_view это может быть как-то включено в мой urls.py но я не уверен, что это сработает.

обновление: я нашел один способ сделать то, что я хочу (см. ниже), но я все равно хотел бы услышать другие способы делающий это.

3 ответов


Я нашел один способ достичь того, чего я хочу, используя прокси-модели, чтобы обойти тот факт, что каждая модель может быть зарегистрирована только один раз.

class PostAdmin(admin.ModelAdmin):
    list_display = ('title', 'pubdate','user')

class MyPosts(Post):
    class Meta:
        proxy = True

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)


admin.site.register(Post, PostAdmin)
admin.site.register(MyPost, MyPostAdmin)

тогда PostAdmin по умолчанию будет доступен в /admin/myapp /post, а список сообщений, принадлежащих пользователю, будет в/admin/myapp / myposts.

посмотрев на http://code.djangoproject.com/wiki/DynamicModels, я придумал следующую функцию утилиты, чтобы сделать то же самое вещь:

def create_modeladmin(modeladmin, model, name = None):
    class  Meta:
        proxy = True
        app_label = model._meta.app_label

    attrs = {'__module__': '', 'Meta': Meta}

    newmodel = type(name, (model,), attrs)

    admin.site.register(newmodel, modeladmin)
    return modeladmin

Это можно использовать следующим образом:

class MyPostAdmin(PostAdmin):
    def get_queryset(self, request):
        return self.model.objects.filter(user = request.user)

create_modeladmin(MyPostAdmin, name='my-posts', model=Post)

Пол Стоун ответ абсолютно велик! Просто добавить, для Django 1.4.5 мне нужно было унаследовать мой пользовательский класс admin.ModelAdmin

class MyPostAdmin(admin.ModelAdmin):
    def queryset(self, request):
        return self.model.objects.filter(id=1)

просто используйте list_filter или date_hierarchy.

date_hierarchy = 'pub_date'

list_filter = ['pub_date',]