Python Django管理员:添加自定义列表视图的最佳方式是什么?

Python Django管理员:添加自定义列表视图的最佳方式是什么?,python,django,django-admin,custom-view,Python,Django,Django Admin,Custom View,我想在管理中提供一个与变更列表视图()非常类似的自定义视图,但没有指向编辑表单视图的链接。用户将能够选择列表中的项目并应用操作,就像在更改列表表单中一样,但他们无权访问编辑表单 我认为ModelAdmin类中的结构应该如下所示: class ProductAdmin(admin.ModelAdmin): def get_urls(self): urls = super(ProductAdmin, self).get_urls() urls += patte

我想在管理中提供一个与
变更列表视图()非常类似的自定义视图
,但没有指向编辑表单视图的链接。用户将能够选择列表中的项目并应用操作,就像在更改列表表单中一样,但他们无权访问编辑表单

我认为ModelAdmin类中的结构应该如下所示:

class ProductAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super(ProductAdmin, self).get_urls()
        urls += patterns('',
            (r'^selectlist/$', self.selectlist_view)
        )
        return urls

    def selectlist_view(self):
        return render_to_response(...)

要返回的视图非常类似于
ModelAdmin.changelist\u view()
。做这件事的最佳干法是什么?

以下自定义ModelAdmin是迄今为止我能想到的最佳解决方案:

class UserModelAdmin(ModelAdmin):
    def get_urls(self):
        urls = super(UserModelAdmin, self).get_urls()
        info = self.model._meta.app_label, self.model._meta.module_name
        select_list_url = patterns('',
            url(r'^selectlist/$', self.selectlist_view, 
                name='%s_%s_select' % info)
        )
        return select_list_url + urls

    def selectlist_view(self, request, extra_context=None):
        temp_list_display_links = self.list_display_links
        self.list_display_links = (None, )
        response = self.changelist_view(request, extra_context)
        self.list_display_links = temp_list_display_links
        return response

我真的不知道为什么,但就我个人而言,我倾向于为一个特定的模型而不是monkeypatching ModelAdmin

编辑:


谢谢,但我需要定制,这不能仅仅通过覆盖模板来完成。例如,显示不同的查询集等

为了显示不同的查询集,可以覆盖ModelAdmin.queryset()

此外,也不能编辑列出的项目。如果我覆盖模板,用户将看不到编辑表单的链接,但如果他能猜到表单的url,他仍然可以访问表单并通过键入url进行编辑,这将是一个安全漏洞

为什么不直接删除相关用户的编辑权限?您还可以覆盖“添加”和“更改”视图:

class SomeModelAdmin(admin.ModelAdmin):
    ...
    def change_view(self, request, object_id, extra_context=None):
        return render_to_response('forbiden_operation.html', dict(op='edit'))
    def ModelAdmin.add_view(self, request, form_url='', extra_context=None):
        return render_to_response('forbiden_operation.html', dict(op='add'))
这些都是“官方”挂钩,将来不太可能断开

还记得“管理之禅”:

Django的管理界面的核心是为单个活动设计的:

编辑结构化内容的可信用户

是的,它非常简单——但这种简单性是基于一系列假设的。Django的管理界面的整个理念直接来自于这些假设,所以让我们在接下来的章节中深入挖掘这个短语的潜台词。 “受信任的用户…”

管理界面是为您(开发人员)信任的人设计的。这不仅仅意味着“经过认证的人”;这意味着Django假定可以信任您的内容编辑器来做正确的事情

这反过来意味着编辑内容没有审批流程——如果你信任你的用户,没有人需要批准他们的编辑。另一个含义是,权限系统虽然功能强大,但在撰写本文时不支持基于每个对象限制访问。如果您信任某人编辑他或她自己的故事,则您信任该用户不会在未经许可的情况下编辑任何其他人的故事

“…编辑…”

Django管理界面的主要目的是让人们编辑数据。这一点一开始似乎很明显,但又产生了一些微妙而强烈的影响

例如,尽管管理界面对于查看数据非常有用(如前所述),但它的设计并没有考虑到这一目的。例如,请注意缺少“可以查看”权限(参见第12章)。Django假设,如果允许人们在管理界面中查看内容,那么他们也可以编辑内容

另一个更重要的要注意的是,即使是远程“工作流”也缺乏任何东西。如果给定的任务需要一系列步骤,则不支持强制按任何特定顺序执行这些步骤。Django的管理界面侧重于编辑,而不是编辑活动。这种对工作流的回避也源于信任原则:管理界面的理念是工作流是一个人事问题,而不是需要在代码中实现的东西

最后,请注意管理界面中缺少聚合。也就是说,不支持显示总计、平均值等。同样,管理界面是用于编辑的——您可以为所有其他界面编写自定义视图

“…结构化内容”

与Django的其余部分一样,管理界面希望您使用结构化数据。因此,它只支持编辑存储在Django模型中的数据;对于任何其他内容,例如存储在文件系统上的数据,都需要自定义视图

句号

现在应该很清楚,Django的管理界面并没有试图让所有人都了解它;相反,我们选择紧紧地专注于一件事,并且把那件事做得非常好

当涉及到扩展Django的管理界面时,基本上也是这样(请注意,“可扩展性”在我们的目标中没有出现)。由于自定义Django视图可以做任何事情,而且它们可以轻松地可视化集成到管理界面(如下一节所述),因此定制管理界面的内置机会在某种程度上受到设计的限制

您应该记住,管理界面“只是一个应用程序”,尽管它非常复杂。它没有做任何Django开发人员有足够时间无法复制的事情。完全有可能将来有人会开发一个基于不同假设集的不同管理界面,从而表现出不同的行为

最后,我们应该指出,在撰写本文时,Django开发人员正在开发一个新版本的管理界面,该界面允许更大的定制灵活性。当您阅读本文时,这些新特性可能已经进入真正的Django发行版。要找出答案,请询问Django社区中的某个人“newforms admin”分支是否已集成


管理员应用程序已经有了很大的改进,以便在定制方面提供更多的灵活性,但我认为“管理员禅”的大部分内容仍然适用。

编辑问题比回答自己的问题要好。:-)这就是我提出的解决方案