How to limit fields in django-admin depending on user?

后端 未结 4 1412
無奈伤痛
無奈伤痛 2020-12-24 12:56

I suppose similar problem would have been discussed here, but I couldn\'t find it.

Let\'s suppose I have an Editor and a Supervisor. I want the Editor to be able to

4条回答
  •  不思量自难忘°
    2020-12-24 13:23

    The problem using the approach outlined by @diegueus9 is that the ModelAdmin acts liked a singleton and is not instanced for each request. This means that each request is modifying the same ModelAdmin object that is being accessed by other requests, which isn't ideal. Below is the proposed solutions by @diegueus9:

    # For example, get_form() modifies the single PostAdmin's fields on each request
    ...
    class PostAdmin(ModelAdmin):
        def get_form(self, request, obj=None, **kwargs):
            if not has_approval_permission(request, obj):
                self.fields = [...] # list of fields to show if user can't approve the post
            else:
                self.fields = ['approved', ...] # add 'approved' to the list of fields if the user can approve the post
    ...
    

    An alternative approach would be to pass fields as a keyword arg to the parent's get_form() method like so:

    ...
    from django.contrib.admin.util import flatten_fieldsets
    
    class PostAdmin(ModelAdmin):
        def get_form(self, request, obj=None, **kwargs):
            if has_approval_permission(request, obj):
                fields = ['approved']
                if self.declared_fieldsets:
                    fields += flatten_fieldsets(self.declared_fieldsets)
    
                # Update the keyword args as needed to allow the parent to build 
                # and return the ModelForm instance you require for the user given their perms
                kwargs.update({'fields': fields})
            return super(PostAdmin, self).get_form(request, obj=None, **kwargs)
    ...
    

    This way, you are not modifying the PostAdmin singleton on every request; you are simply passing the appropriate keyword args needed to build and return the ModelForm from the parent.

    It is probably worth looking at the get_form() method on the base ModelAdmin for more info: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/options.py#L431

提交回复
热议问题