Home > Enterprise >  Django- how to add user profile permissions based for selected users
Django- how to add user profile permissions based for selected users

Time:03-30

In my Django app, I have a user_profile model (below). Each user has an is_adm boolean value:

user_profile/models.py:

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField('username', max_length=50, unique=True)
    email = models.EmailField('email address', unique=True)
    first_name = models.CharField(max_length=20, blank=True, null=True)
    last_name = models.CharField(max_length=20, blank=True, null=True)
    is_adm = models.BooleanField(default=False)

Separately I have a posts model for blog posts. There is an admin panel for this model where you can add a new Post instance. You can also update, delete or view other Post instances there.

posts/models.py:

class Posts(models.Model):
    title = models.CharField(max_length=300, default='')
    publish_date = models.DateField(blank=True, null=True)
    author = models.CharField(max_length=300)
    copy = models.TextField(blank=True, default='')
    link = models.URLField(blank=True)
    source = models.TextField(default='', blank=True)
    published = models.BooleanField(default=False)

I want the ability for is_adm = True users to be able to:

  • add a Post model instance in the admin panel
  • delete any Post model instance in the admin panel
  • view any Post model instance in the admin panel
  • edit fields in the Posts admin panel

I know that Django has Permissions and Authorization: https://docs.djangoproject.com/en/2.2/topics/auth/default/#permissions-and-authorization

But how do I add these methods like: has_view_permission(), has_add_permission(), has_change_permission() and has_delete_permission()...

... for is_adm = True users so that they can add, delete, view and change Post model instances through the Post admin panel?

CodePudding user response:

I propose you two solutions. I am sure about the first one because I use it on a personal project. However, I never tested the second one.

Create Admin Manager

You can create a specific admin manager for your Posts model and override the methods which manage the permissions.

The following code gives all permissions if the user of the request has is_adm to True, otherwise it gives the default permission value.

from django.contrib.admin import ModelAdmin, register

@register(Posts)
class PostsAdmin(ModelAdmin):
    def has_add_permission(self, request):
        if request.user.is_adm:
            return True
        return super().has_add_permission(request)

    def has_view_permission(self, request, obj):
        if request.user.is_adm:
            return True
        return super().has_view_permission(request, obj)

    def has_change_permission(self, request, obj):
        if request.user.is_adm:
            return True
        return super().has_change_permission(request, obj)

    def has_delete_permission(self, request, obj):
        if request.user.is_adm:
            return True
        return super().has_delete_permission(request, obj)

Modify your User

An other solution could be to override the has_perm method of your custom User which is inherits from PermissionsMixin.

The following code should give all permissions if the user has is_adm to True and the object is an instance of Posts.

class User(AbstractBaseUser, PermissionsMixin):
    username = models.CharField('username', max_length=50, unique=True)
    email = models.EmailField('email address', unique=True)
    first_name = models.CharField(max_length=20, blank=True, null=True)
    last_name = models.CharField(max_length=20, blank=True, null=True)
    is_adm = models.BooleanField(default=False)

    def has_perm(self, perm, obj=None):
        if self.is_adm and isinstance(obj, Posts):
            return True
        return super().has_perm(perm, obj)
  • Related