Django管理员中同一模型的多个ModelAdmins /视图

发布于 2021-01-29 17:04:42

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

假设我有一个称为Posts的Django模型。默认情况下,此模型的admin视图将列出所有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)

默认情况下,可以通过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中可能包含这样的函数,但是我不确定它是如何工作的。

更新 :我找到了一种实现自己想要的方式(见下文),但是我仍然想听听其他实现方式。

关注者
0
被浏览
272
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

    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网址为/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)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看