我有两个Django管理员的特殊用例,我对其他人的意见很好奇:
我想使用管理员的自定义版本,允许用户编辑网站上的某些对象(自定义看起来更像网站的其余部分)。此时,用户只能编辑他们拥有的对象,但我最终会将其打开到更多wiki风格,任何用户都可以编辑任何对象。换句话说,我将所有用户指定为“员工”,并授予他们编辑这些对象的权限。
我正在考虑为其他对象执行此操作,并非所有用户都能编辑所有对象。我使用自定义视图来确保用户只编辑自己的对象。好处是我有一个编辑界面的起点(因为管理员自动创建它)我可以用ModelAdmin自定义,因为管理功能已经非常接近我想要的。
我觉得第一个建议被认为是可以接受的,而第二个可能不是。在查看了一些其他资源(Valid use case for django admin?和该问题中Django Book的引用之后),似乎有些Django开发人员认为这是错误的想法。
我的问题是:为什么?是否有充分的理由不使用自定义管理视图来从性能,稳定性,安全性,可用性等角度授予每个对象的权限?在我看来,它可以节省大量的时间用于某些应用程序(我最终可能会这样做)但我想了解在管理员和其他所有内容之间进行区分的原因。
答案 0 :(得分:4)
你可以自由地做任何你想做的事。如果你想自定义Django管理员,那就去吧,但是一旦偏离了典型的管理员修改路径,你可能就不会受到邮件列表和IRC的支持。
虽然现在定制管理员可能看起来像是一个简单的解决方案,但更有可能的是,只要你真正尝试调整工作方式,就自己重新创建必要的表单。查看generic create/edit/delete和generic details/list视图 - 它们将非常快速地展示您需要的基本功能,并且比管理员更容易扩展。
我认为“管理员不是你的应用程序”的观点来自于这样一个事实:使用其他机制比攻击管理员更容易(另外,保持管理员不受影响,使Django开发人员更容易向前兼容) 。
答案 1 :(得分:2)
我之前已经制作了一个django应用程序,而无需修改实际的管理代码。而是创建一个admin.ModelAdmin的子类,其中有几个方法使用queryset过滤器进行扩展。这将仅显示用户拥有的记录(在这种情况下,business是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)
答案 2 :(得分:1)
我们限制Django Admin - 未经修改 - 用于我们的管理员和支持人员的“后台”访问。不是由用户或客户。一些样式表更改,使颜色与网站的其余部分一致,但就是这样。
对于用户(我们的客户),我们提供适当的视图功能来执行各种交易。即使使用量身定制的表格,我们仍需要检查和控制一些事项。
Django更新事务编写非常简单,尝试自定义管理员似乎更多的是编写事务本身。
我们的交易并不比http://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view中显示的复杂得多。
通常,具有事务的页面几乎总是包含工作流元素(或相关内容),这使得它们比内置管理界面稍微复杂一些。我们将在样板之外添加大约6行代码。
我们的用例不是简单的添加/更改/删除,因此我们需要比默认管理应用提供的更多功能。