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
Postsadmin 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)
