限制Django管理员更改权限

时间:2012-07-19 20:39:03

标签: django django-admin

我试图限制群组中的用户无法更改其群组无权更改的字段。例如:

class StudentReferral(models.Model):
    teacher = models.CharField(max_length=50)
    referral_first_name = models.CharField(max_length=50)
    referral_last_name = models.CharField(max_length=50)
    accepted = models.BooleanField(blank=True)

现在教师都在一个用户组中,接受或拒绝推荐的人在另一个用户组中。教师用户组应该只能编辑以下字段:teacherreferral_first_namereferral_last_name。其他用户组应该只能编辑接受的字段。两个小组都应该能够看到所有的字段。

django中是否有内置功能可以实现这一目标或者采用自定义方式实现这一目标?

1 个答案:

答案 0 :(得分:7)

覆盖ModelAdmin.get_fieldsets,并执行以下操作:

class MyModelAdmin(admin.ModelAdmin):
    ...
    fieldsets = (
        ... # Standard/all fields
    )
    teacher_fieldsets = (
        ... # Only fields teachers can see
    )

    def get_fieldsets(self, request, obj=None):
        if request.user.groups.filter(name='Teachers').exists():
            return self.teacher_fieldsets
        else:
            return super(MyModelAdmin, self).get_fieldsets(request, obj=obj)

修改

抱歉,我错过了一些关于他们仍然可以看到所有字段的信息,只是没有编辑它们。我原来的答案完好无损,因为它可能对你有用。但是,为此,您需要覆盖ModelAdmin.get_readonly_fields

class MyModelAdmin(admin.ModelAdmin):
    ...
    readonly_fields = ('teacher', 'referral_first_name', 'referral_last_name')
    teacher_readonly_fields = ('accepted',)

    def get_readonly_fields(self, request, obj=None):
        if request.user.groups.filter(name='Teachers').exists():
            return self.teacher_readonly_fields
        else:
            return super(MyModelAdmin, self).get_readonly_fields(request, obj=obj)

我在这里假设选择只是老师或“其他用户”。如果要考虑其他类型,或者您不希望在一种情况下字段受限,则可能需要删除readonly_fields属性并将其替换为other_readonly_fields之类的内容,并相应地进行分支( readonly_fields的默认值仅为模型上editable=False的字段。

另外,请注意,如果需要字段,则也不能将其设置为只读。如果其中一些是必填字段,您还需要覆盖ModelForm.__init__,以便在它们是只读的情况下不需要它们,这需要一些额外的hackery(ModelForm不通常无法访问request

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(MyModelForm, self).__init__(*args, **kwargs)

        if self.request is not None:
            if self.request.user.groups.filter(name='Teachers').exists():
                self.fields['accepted'].required = False

class MyModelAdmin(admin.ModelAdmin):
    form = MyModelForm
    ...
    def get_form(self, request, obj=None, **kwargs):
        ModelForm = super(MyModelAdmin, self).get_form(request, obj=obj, **kwargs)
        class WrapperModelForm(ModelForm):
            def __new__(cls, *args, **kwargs):
                kwargs['request'] = request
                return ModelForm(*args, **kwargs)
        return WrapperModelForm