Django管理中相同模型的多个模型管理/视图

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (40)

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

假设我有一个Django模型叫做post。默认情况下,此模型的管理视图将列出所有POST对象。

我知道我可以通过设置诸如list这样的变量,以各种方式自定义页面上显示的对象列表。_显示或重写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...。但是,我希望拥有同一个模型的多个视图/模型管理。/admin/myapp/post列出所有POST对象,以及/admin/myapp/myposts将列出属于用户的所有帖子,以及/admin/myapp/draftpost可以列出所有尚未发布的帖子(这些只是例子,我的实际用例要复杂得多)。

不能为同一个模型注册多个ModelAdmin(这将导致AlreadyRegistered例外情况)。理想情况下,我想实现这一点将所有内容放入单个ModelAdmin类,并编写自己的“URL”函数,根据URL返回不同的查询集。

我看过Django源代码,我看到的函数如下ModelAdmin.changelist_view这可以在我的urls.py中包含,但我不确定它到底是如何工作。

提问于
用户回答回答于

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

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/mypost。

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)

扫码关注云+社区