Django admin中相同模型的多个ModelAdmins /视图

Pau*_*one 145 python django django-admin

如何为同一模型创建多个ModelAdmin,每个模型以不同方式自定义并链接到不同的URL?

假设我有一个名为Posts的Django模型.默认情况下,此模型的管理视图将列出所有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)
Run Code Online (Sandbox Code Playgroud)

默认情况下,可以通过URL访问它/admin/myapp/post.但是我想拥有相同模型的多个视图/ ModelAdmins.例如/admin/myapp/post,列出所有帖子对象,并/admin/myapp/myposts列出属于该用户的/admin/myapp/draftpost所有帖子,并列出所有尚未发布的帖子.(这些只是示例,我的实际用例更复杂)

您不能为同一模型注册多个ModelAdmin(这会导致AlreadyRegistered异常).理想情况下,我希望在将所有内容放入单个ModelAdmin类并编写自己的"urls"函数的情况下实现此目的,以根据URL返回不同的查询集.

我已经看过Django源了,我看到这样的函数ModelAdmin.changelist_view可能以某种方式包含在我的urls.py中,但我不确定它究竟是如何工作的.

更新:我找到了一种做我想做的事情(见下文),但我仍然希望听到其他方法.

Pau*_*one 258

我找到了一种方法来实现我想要的,通过使用代理模型来解决每个模型只能注册一次的事实.

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)
Run Code Online (Sandbox Code Playgroud)

然后可以在/ admin/myapp/post访问默认的PostAdmin,用户拥有的帖子列表位于/ 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
Run Code Online (Sandbox Code Playgroud)

这可以使用如下:

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

create_modeladmin(MyPostAdmin, name='my-posts', model=Post)
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了.我不知道可以在管理站点中注册代理模型.这实际上对我有很大帮助. (8认同)
  • 我还需要在django admin中两次注册相同的模型,代理模型似乎有效.但我发现权限系统存在一个问题.见这里:http://code.djangoproject.com/ticket/11154 (8认同)
  • 更改默认管理器而不是ModelAdmin查询集也是一个好主意.因此,即使在管理员之外,代理模型的行为也是一致的. (4认同)
  • 现在真正的答案是,为什么django不会让你有两个管理员用于同一型号?我们不应该只需要检查两行来检查并抛出错误:s.还是很棒的答案! (4认同)
  • bjunix你设法解决了权限问题吗? (2认同)