2

我有几个 Django 管理员的特殊用例,我很好奇其他人的意见:

  1. 我想使用管理员的定制版本来允许用户编辑网站上的某些对象(定制为看起来更像网站的其他部分)。在这一点上,用户只能编辑他们拥有的对象,但我最终会将其开放为更具 wiki 风格的东西,任何用户都可以编辑任何对象。换句话说,我会将所有用户指定为“员工”并授予他们编辑这些对象的权限。

  2. 我正在考虑对并非所有用户都能够编辑所有对象的其他对象也这样做。我会使用自定义视图来确保用户只编辑他们自己的对象。好处是我将有一个编辑界面的起点(因为管理员会自动创建它),我可以使用 ModelAdmin 自定义它,因为管理功能已经非常接近我想要的。

我觉得第一个建议会被认为是可以接受的,而第二个可能不会。在检查了一些其他资源(Django admin 的有效用例?以及该问题中 Django Book 中的引用)之后,似乎一些 Django 开发人员觉得这是错误的想法。

我的问题是:为什么?从性能、稳定性、安全性、可用性等角度来看,是否有充分的理由不使用自定义管理视图来授予每个对象的权限?在我看来,它可以为某些应用程序节省大量时间(而且我最终可能会这样做),但我想了解在管理员和其他一切之间做出这种区分的原因。

4

3 回答 3

4

你可以自由地做任何你想做的事。如果你想自定义 Django 管理员,那就去做吧,但是一旦你偏离了典型的管理员修改路径,邮件列表和 IRC 可能不会很好地支持你。

虽然现在自定义管理员似乎是一个简单的解决方案,但一旦你真正尝试调整事情的工作方式,它很可能不仅仅是自己重新创建必要的表单。查看通用的创建/编辑/删除通用的详细信息/列表视图——它们将很快公开您需要的基本功能,并且比管理员更容易扩展。

我相信“管理员不是你的应用程序”的观点来自这样一个事实,即使用其他机制比破解管理员更容易(另外,保持管理员不变使得 Django 开发人员更容易向前兼容)。

于 2009-10-21T01:30:13.153 回答
2

我之前已经让一个 django 应用程序在不修改实际管理代码的情况下精确地做到这一点。而是通过使用查询集过滤器扩展的几个方法创建 admin.ModelAdmin 的子类。这将仅显示用户拥有的记录(在这种情况下,业务是 AUTH_PROFILE_MODEL)。网上有很多关于如何实现这一点的博客。

您可以使用此技术过滤列表、表单选择框、表单字段验证保存等。

到目前为止,它从 NFA 到 1.0 到 1.1 都幸存下来,但这种方法容易受到 api 变化的影响。

在实践中,我发现为应用程序中的新模型生成新的行级别访问级别管理表单要快得多,因为我已经添加了它们。您只需使用用户 fk 创建一个新模型,子类化 AdminFilterByBusiness 或只是

admin.site.register(NewModel,AdminFilterByBusiness)

如果它不需要任何定制。它有效并且非常干燥。

但是,您确实冒着无法利用其他已发布的 django 应用程序的风险。因此,请为您正在构建的项目仔细考虑这种技术。

下面的示例过滤器管理类受http://code.djangoproject.co/wiki/NewformsHOWTO的启发

#AdminFilterByBusiness {{{2
class AdminFilterByBusiness(admin.ModelAdmin):
    """
    Used By News Items to show only objects a business user is related to
    """
    def has_change_permission(self,request,obj=None):
        self.request = request

        if request.user.is_superuser:
            return True

        if obj == None:
            return  super(AdminFilterByBusiness,self).has_change_permission(request,obj)

        if obj.business.user == request.user:
            return True
        return False

    def has_delete_permission(self,request,obj=None):

        self.request = request

        if request.user.is_superuser:
            return True

        if obj == None:
            return  super(AdminFilterByBusiness,self).has_delete_permission(request,obj)

        if obj.business.user == request.user:
            return True
        return False

    def has_add_permission(self, request):

        self.request = request
        return super(AdminFilterByBusiness,self).has_add_permission(request)

    def queryset(self, request):
        # get the default queryset, pre-filter
        qs = super(AdminFilterByBusiness, self).queryset(request)
        #
        if not (request.user.is_superuser):
            # filter only shows blogs mapped to currently logged-in user
            try:
                qs = qs.filter(business=request.user.business_set.all()[0])
            except:
                raise ValueError('Operator has not been created. Please Contact Admins')
        return qs

    def formfield_for_dbfield(self, db_field, **kwargs):

        """ Fix drop down lists to populate as per user request """
        #regular return for superuser
        if self.request.user.is_superuser:
            return  super(AdminFilterByBusiness, self).formfield_for_dbfield(
                    db_field, **kwargs)

        if db_field.name == "business":
            return forms.ModelChoiceField(
                queryset = self.request.user.business_set.all()
               )

        #default
        return  super(AdminFilterByBusiness, self).formfield_for_dbfield(db_field, **kwargs)
于 2009-10-21T04:55:46.423 回答
1

我们限制了 Django Admin(未经修改),以便我们的管理员和支持人员访问“后台”。不是用户或客户。一些样式表更改以使颜色与站点的其余部分保持一致,但仅此而已。

对于用户(我们的客户),我们提供适当的查看功能来进行各种交易。即使有大量定制的表格,我们仍然需要检查和控制一些事情。

Django 更新事务编写起来非常简单,尝试自定义 admin 似乎比编写事务本身需要更多的工作。

我们的交易并不比http://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view中显示的复杂多少。

通常,我们的具有事务的页面几乎总是包含工作流元素(或相关内容),这使得它们比内置管理界面稍微复杂一些。除了样板文件之外,我们还会有大约六行额外的代码。

我们的用例不是简单的添加/更改/删除,因此我们需要比默认管理应用程序提供的更多功能。

于 2009-10-21T10:19:55.213 回答