Field Level Permission Django
Asked Answered
C

4

18

Today i came up with a requirement where i need to implement field level permission so looking for the best possible way.

class ABC(models.Model):
    field1 = .....
    field2 = .....
    field3 = .....

Create two groups(A and B) and assigned permission that both one can add/edit/delete and the other can only add/edit. But now need some help in this :-

I want if the first group user logs in in the admin he should be able to see all the three fields but if second group user logs in they should only see field1.

I want this in django admin as i need to perform some manipulations after these.My django version is 1.3

Thanks in advance

Cohabit answered 5/12, 2013 at 11:6 Comment(3)
You want this in the django-admin, or you have your own? The requirement is not very clearOvertrick
I want this in django admin . Django 1.3Cohabit
Well in that case, AFAIK, you are in for some serious hacking. This is not something Django admin can handle out of the box.Overtrick
G
5

In your admin.py

class ABCAdmin(admin.ModelAdmin):
    fields = [.....]  # here comes the fields open to all users

    def change_view(self, request, object_id, extra_context=None):  # override default admin change behaviour
        if request.user in gruop2:  # an example 
            self.fields.append('field2')  # add field 2 to your `fields` 
            self.fields.append('field3')  # add field 3 to your `fields`

You can use the docs to see what is available. Above is an example taken from one of my usages. You may also need to define change_view and add_view too.

Gesticulation answered 5/12, 2013 at 12:2 Comment(2)
def get_form(self, request, obj=None, **kwargs): if request.user.groups.filter(name="Group 1"): self.exclude = ("is_approved", ) form = super(SupplierAdmin, self).get_form(request, obj, **kwargs) return formCohabit
Still the field is appearing !Cohabit
B
4

Just in case someone else stumble about this, I had some issues with the given accepted answer. Every time the view got refreshed, it appended the fields over and over again. As well to the desired restricted view, where it shouldn't appear.

So, according to the docs, I made it working as follows:

Creating a custom ModelForm

class AbcStaffForm(ModelForm):
    class Meta:
        model = Abc
        exclude = ["manager", "foo", "bar",]

Overwrite get_form() in AbcModelAdmin & refered the custom ModelForm

class AbcAdmin(admin.ModelAdmin):
    # some other code
    # ...
    def get_form(self, request, obj=None, **kwargs):
        if not request.user.is_superuser:
            kwargs['form'] = AbcStaffForm  # ModelForm

        return super().get_form(request, obj, **kwargs)
Blowup answered 1/8, 2019 at 16:1 Comment(0)
F
2

You can also override readonly_fields in changeform_view.

Try this in admin.py

class ABCAdmin(admin.ModelAdmin):

    def changeform_view(self, request, *args, **kwargs)
        self.readonly_fields = list(self.readonly_fields)
        if request.user in group:  #or another condition
            self.readonly_fields.append('field2')

        return super(ABCAdmin, self).changeform_view(request, *args, **kwargs)
Footstool answered 26/6, 2019 at 13:2 Comment(0)
P
0

Overwrite get_fields() in ABCAdmin (group B cannot view "is_on" field):

class ABCAdmin(admin.ModelAdmin):
    fields = ['name', 'title', 'price', 'is_on', 'create_time']

    def get_fields(self, request, obj=None):
        if request.user in groupB:
            if 'is_on' not in self.fields:
                self.fields.append('is_on')
        else:
            if 'is_on' in self.fields:
                self.fields.remove('is_on')
        return super(ABCAdmin, self).get_fields(request, obj)
Purvis answered 11/8, 2022 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.