限制Django管理员更改权限

CF7*_*711 4 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)
Run Code Online (Sandbox Code Playgroud)

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

是否有内置于django中的内容可以实现这一目标或自定义方式?

Chr*_*att 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)
Run Code Online (Sandbox Code Playgroud)

编辑

对不起,我错过了一点,他们仍然可以看到所有字段,只是不能编辑它们.我原来的答案完好无损,因为它可能对你有用.但是,为此,您需要覆盖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)
Run Code Online (Sandbox Code Playgroud)

我在这里假设选择只是老师或"其他用户".如果还有其他类型需要考虑,或者您不希望在一种情况下对字段进行限制,您可能希望删除该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
Run Code Online (Sandbox Code Playgroud)