我试图限制群组中的用户无法更改其群组无权更改的字段。例如:
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)
现在教师都在一个用户组中,接受或拒绝推荐的人在另一个用户组中。教师用户组应该只能编辑以下字段:teacher
,referral_first_name
和referral_last_name
。其他用户组应该只能编辑接受的字段。两个小组都应该能够看到所有的字段。
django中是否有内置功能可以实现这一目标或者采用自定义方式实现这一目标?
答案 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