Несколько 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',]