如何为同一个模型创建多个 ModelAdmin,每个模型都以不同方式定制并链接到不同的 URL?
假设我有一个名为 Posts 的 Django 模型。默认情况下,此模型的管理视图将列出所有 Post 对象。
我知道我可以通过设置诸如 list_display 之类的变量或覆盖queryset我的 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。但是我想拥有同一个模型的多个视图/模型管理员。例如/admin/myapp/post,将列出所有帖子对象,并/admin/myapp/myposts列出属于用户的/admin/myapp/draftpost所有帖子,并可能列出所有尚未发布的帖子。(这些只是例子,我的实际用例更复杂)
/admin/myapp/post
/admin/myapp/myposts
/admin/myapp/draftpost
您不能为同一模型注册多个 ModelAdmin(这会导致AlreadyRegistered异常)。理想情况下,我希望在 不 将所有内容放入单个 ModelAdmin 类并编写自己的“urls”函数来根据 URL 返回不同的查询集的情况下实现这一点。
AlreadyRegistered
我查看了 Django 源代码,发现这样的函数ModelAdmin.changelist_view可能会以某种方式包含在我的 urls.py 中,但我不确定它究竟是如何工作的。
ModelAdmin.changelist_view
更新 :我找到了一种做我想做的事的方法(见下文),但我仍然想听听其他方法。
我找到了一种方法来实现我想要的,通过使用代理模型来解决每个模型只能注册一次的事实。
class PostAdmin(admin.ModelAdmin): list_display = ('title', 'pubdate','user') class MyPost(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可以在 at 访问,/admin/myapp/post并且用户拥有的帖子列表将在 at /admin/myapp/myposts。
PostAdmin
在查看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)