我正在尝试为允许具有不同权限的用户执行不同操作的模型编写动态表单。我希望下面的代码正常运行,以便非超级用户无法编辑“商家”块中的任何字段。
class CategoryModelAdmin(LWModelAdmin):
fieldsets = (
('Merchant', {'fields': ('merchant',) }),
('Category', { 'fields': ('name', 'parent',) }),
)
def get_form(self,request,obj=None, **kwargs):
if request.user.is_superuser:
self.exclude = []
else:
self.exclude = ['Merchant']
return super(CategoryModelAdmin,self).get_form(request, obj=None, **kwargs)
虽然我可以通过下面的代码实现这种效果,但我真的在寻找“正确”的方式来实现它,感觉使用排除是可行的方式,但我似乎无法做到正确无论我尝试什么。
class CategoryModelAdmin(LWModelAdmin):
declared_fieldsets = None
admin_fieldsets = (
(None, {'fields': ('merchant',) }),
('Category', { 'fields': ('name', 'parent',) }),
)
restricted_fieldsets = (
('Category', { 'fields': ('name', 'parent',) }),
)
def get_fieldsets(self, request, obj=None):
if request.user.is_superuser:
fieldsets = self.admin_fieldsets
else:
fieldsets = self.restricted_fieldsets
return LWModelAdmin.fieldsets + fieldsets
def get_form(self, request, obj=None, **kwargs):
self.declared_fieldsets = self.get_fieldsets(request, obj)
return super(self.__class__, self).get_form(request, obj)
答案 0 :(得分:3)
您的代码不是线程安全的,您不应在自定义ModelAdmin方法中设置self(self.exclude
等)的属性。而是使用ModelAdmin.get_form
和InlineModelAdmin.get_formset
的kwargs来获得你想要的东西。
这是一个简单的例子:
class CategoryModelAdmin(LWModelAdmin):
def get_form(self, request, obj=None, **kwargs):
if request.user.is_superuser:
kwargs['exclude'] = ['foo', 'bar',]
else:
kwargs['fields'] = ['foo',]
return super(CategoryModelAdmin, self).get_form(request, obj, **kwargs)
答案 1 :(得分:1)
我不确定这是否会或多或少是黑客攻击,但你有没有考虑过这个?
创建两个不同的模型,指向同一个表。每个型号 可以拥有自己的ModelAdmin类,无论你想要什么设置。 然后使用Django的权限使其中一个不可见 非管理员。
如果您想避免重复代码,可以派生出两个代码 来自您创建的一些公共基类的类。
优点是你不会在文档中所写的内容之外做任何事情。我认为我们不应该覆盖get_form
和get_fieldsets
等方法。如果它们不是发布的API的真正组成部分,那么这些方法可能会在当天发生变化或被删除,并且您可能会在升级中拥有。
只是一个想法...