【问题标题】:Restricting Django Admin Change Permissions限制 Django 管理员更改权限
【发布时间】:2012-07-19 20:39:03
【问题描述】:

我试图限制组中的用户能够更改他们的组无权更改的字段。例如:

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 中是否有内置的东西使这成为可能,或者有一种自定义的方式来做到这一点?

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    覆盖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
    

    【讨论】:

      猜你喜欢
      • 2011-09-29
      • 1970-01-01
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 2015-02-05
      • 2021-02-28
      • 2011-01-18
      相关资源
      最近更新 更多