Djangopipe理中的同一模型的多个ModelAdmins / views
我如何为同一个模型创build多个ModelAdmin,每个模型都有不同的定制,并链接到不同的URL?
假设我有一个名为Posts的Django模型。 默认情况下,此模型的pipe理视图将列出所有Post对象。
我知道我可以通过设置像list_display这样的variables或者在我的ModelAdmin中重写queryset
方法来以各种方式自定义页面上显示的对象列表,如下所示:
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)
默认情况下,这可以通过URL /admin/myapp/post
。 不过,我想有相同模型的多个视图/ ModelAdmins。 例如/admin/myapp/post
会列出所有的post对象,而/admin/myapp/myposts
会列出属于用户的所有post,而/admin/myapp/draftpost
可能会列出所有尚未发布的post。 (这些只是例子,我的实际使用情况更复杂)
您不能为同一模型注册多个ModelAdmin(这会导致AlreadyRegistered
exception)。 理想情况下,我希望实现这一点, 而不是把所有东西都放到一个ModelAdmin类中,并编写我自己的'urls'函数,根据URL返回不同的查询集。
我看了一下Django的源代码,并且看到了像ModelAdmin.changelist_view
这样的函数,它可能会被包含在我的urls.py中,但是我不确定这是如何工作的。
更新 :我已经find了一种做我想做的方式(见下文),但是我仍然希望听到其他的做法。
我find了一种方法来实现我想要的,通过使用代理模型来解决事实,即每个模型可能只注册一次。
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访问,用户拥有的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)
只需使用一个list_filter或date_hierarchy。
date_hierarchy = 'pub_date' list_filter = ['pub_date',]
保罗·斯通的答案绝对好! 只是为了添加,对于Django 1.4.5我需要从admin.ModelAdmin
inheritance我的自定义类
class MyPostAdmin(admin.ModelAdmin): def queryset(self, request): return self.model.objects.filter(id=1)