5

我正在尝试为模型编写一个动态表单,以允许具有不同权限的用户执行不同的操作。我希望以下代码能够正常运行,以便非超级用户无法编辑“商家”块中的任何字段。

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)

虽然我可以通过下面的代码实现这种效果,但我真的在寻找“正确”的方法来做到这一点,感觉就像使用 exclude 是要走的路,但无论如何我似乎都无法做到我试试。

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)
4

2 回答 2

3

您的代码不是线程安全的,您不应在自self.exclude定义 ModelAdmin 方法中设置 self (等)的属性。而是使用 kwargs of ModelAdmin.get_formandInlineModelAdmin.get_formset来获得你想要的东西。

这是一个简单的例子:

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)
于 2011-07-22T07:07:44.053 回答
1

我不确定这或多或少是一种黑客行为,但你考虑过这个吗?

创建两个不同的模型,指向同一个表。每个模型都可以拥有自己的 ModelAdmin 类,可以进行任何你想要的设置。然后使用 Django 的权限使其中一个对非管理员不可见。

如果你想避免重复代码,你可以从你创建的一些公共基类派生你的两个类。

优点是您不会在文档中写的内容之外做任何事情。我不认为我们打算覆盖诸如get_formand之类的方法get_fieldsets。如果它们不是已发布 API 的真正组成部分,那么这些方法可能会在当天更改或删除,您可能会在升级中获得所有权。

只是一个想法...

于 2011-07-22T03:13:02.720 回答