Restricting Django Admin Change Permissions

前端 未结 1 796
既然无缘
既然无缘 2020-12-15 14:12

I am trying to restrict users in groups from being able to change fields their group does not have permission to change. For example:

class StudentReferral(m         


        
相关标签:
1条回答
  • 2020-12-15 14:50

    Override ModelAdmin.get_fieldsets, and do something like the following:

    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)
    

    EDIT

    Sorry, I missed the bit about they should still be able to see all fields, just not edit them. I've left the original answer intact, as it might still be of use to you. For this, though, you'll need to override 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)
    

    I'm assuming here that the choices are only teacher or "other user". If there's other types to consider, or you don't want the fields limited at all in one circumstance, you might want to remove the readonly_fields attribute and replace it with something like other_readonly_fields, and branch accordingly (the default value for readonly_fields is only those fields that have editable=False on the model).

    Also, be aware that if a field is required, you can't make it read-only as well. If some of these are required fields, you'll need to override ModelForm.__init__ as well, to make them not required in the circumstances where they will be read-only, which requires some extra hackery (ModelForm doesn't have access to request, normally):

    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
    
    0 讨论(0)
提交回复
热议问题