根据权限交换在AdminPage中呈现的字段类型/窗口小部件

时间:2012-01-20 16:01:19

标签: python django django-admin django-modeladmin

在标题中,我想将渲染的字段交换到表单上。 例如,我有以下模型:

models.py
class Project(models.Model):
    name = models.TextField(max_length=200)
    finished = models.BoolenField(default=False)

admin.py
class ProjectAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            #here change the name field form TextField 
            #to a disabled TextField or to other Field defined by me
            self.form['name']['widget] = MySuperDuperWidgetField() #or smth like that

有可能吗?

2 个答案:

答案 0 :(得分:1)

您必须覆盖ModelAdmin子类中的formfield_for_dbfield方法。在其中,您可以检查请求,当前用户和对象实例,并确定要使用的正确表单域(使用您需要的任何自定义窗口小部件)

(formfield_for_dbfield未记录,因此请自担风险:))如果您知道相关字段是外键,m2m或选择字段,那么有文档化的方法可以覆盖这些字段。

答案 1 :(得分:1)

是的,这是可能的,但不完全像你拥有它:

class ProjectAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        ModelForm = super(ProjectAdmin, self).get_form(request, obj=None, **kwargs)
        class PermissionedModelForm(ModelForm):
            def __init__(self, *args, **kwargs):
                super(PermissionedModelForm, self).__init__(*args, **kwargs)

                if request.user.is_superuser:
                    self.fields['name'].widget = MySuperDuperWidgetField()

        return PermissionedModelForm

修改

实际上,对于像改变字段小部件这样简单的东西来说,@ IanClelland的答案更合适,但是如果你需要做更复杂的事情,那么这种方法是可行的。