代码之家  ›  专栏  ›  技术社区  ›  John Debs

Django管理员的特定用例

  •  2
  • John Debs  · 技术社区  · 15 年前

    我为Django管理员提供了几个特殊的用例,我对其他人的意见很好奇:

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

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

    我觉得第一个建议可以接受,而第二个可能不行。在签出一些其他资源之后( Valid use case for django admin? 在这个问题上,django书中的引用)似乎有些django开发人员认为这是错误的想法。

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

    3 回复  |  直到 13 年前
        1
  •  4
  •   Wladimir Palant    13 年前

    你可以随心所欲。如果您想自定义django管理,请继续使用它,但是一旦您偏离了典型的管理修改路径,邮件列表和IRC可能就不太支持您。

    虽然定制管理现在看起来似乎是一个简单的解决方案,但如果你真的试图调整事情的工作方式,那么很可能不仅仅是自己重新创建必要的表单,而是更多的工作。窥视 generic create/edit/delete generic details/list 视图——它们将很快地公开您需要的基本功能,并且比管理员更易于扩展。

    我相信“admin不是你的应用”的观点来自这样一个事实,即使用其他机制比黑客管理更容易(另外,让admin保持原样可以使django开发人员更容易实现前向兼容性)。

        2
  •  2
  •   michael    15 年前

    我以前让一个django应用程序在不修改实际管理代码的情况下精确地执行这个操作。相反,通过创建一个子类admin.modeladmin,它的几个方法通过查询集过滤器扩展。这将只显示用户拥有的记录(在本例中,业务是auth_profile_模型)。网上有很多关于如何实现这一目标的博客。

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

    到目前为止,它从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)
    
        3
  •  1
  •   S.Lott    15 年前

    我们限制django管理员(未修改)对管理员和支持人员的“后台”访问权限。不是由用户或客户。一些样式表的更改使颜色与网站的其他部分一致,但就是这样。

    对于用户(我们的客户),我们提供适当的视图功能来执行各种事务。即使有大量定制的表单,我们仍然需要检查和控制一些东西。

    Django更新事务非常容易编写,并且尝试自定义管理似乎比编写事务本身更有效。

    我们的交易并不比 http://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view .

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

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