I have a django app. And I added in the admin panel of django the following permission:
Accounts | account | Can view account
And in the code of admin.py of the accounts app. I have added this:
from django.contrib.auth import get_user_model
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from .models import Account
# from .models import *
# Register your models here.
User = get_user_model()
user = User.objects.get(email='n@n.nl')
print(user.has_perm('view_account'))
content_type = ContentType.objects.get_for_model(Account)
permission = Permission.objects.get(
codename='view_account', content_type=content_type)
user.user_permissions.add(permission)
permissions = Permission.objects.filter(content_type=content_type)
for perm in permissions:
print(f"Codename: {perm.codename}, Name: {perm.name}")
print(user)
class AccountAdmin(UserAdmin):
list_display = (
"email",
"first_name",
"last_name",
"username",
"last_login",
"date_joined",
"is_active",
)
list_display_links = ("email", "first_name", "last_name")
filter_horizontal = (
'groups',
'user_permissions',
)
readonly_fields = ("last_login", "date_joined")
ordering = ("-date_joined",)
list_filter = ()
User = get_user_model()
user = User.objects.get(email='n@n.nl')
content_type = ContentType.objects.get_for_model(Account)
permission = Permission.objects.get(
codename='view_account', content_type=content_type)
user.user_permissions.add(permission)
admin.site.register(Account, AccountAdmin)
acount - models.py:
from django.contrib.auth.models import (
AbstractBaseUser, BaseUserManager, PermissionsMixin)
from django.db import models
from django.contrib.auth.models import Permission
from .decorators import allowed_users
# Create your models here.
class MyAccountManager(BaseUserManager):
@allowed_users(allowed_roles=['account_permission'])
def create_user(self, email, password=None, **extra_field):
if not email:
raise ValueError("Gebruiker moet een email adres hebben.")
if not password:
raise ValueError("Gebruiker moet een password hebben.")
user = self.model(email=email, **extra_field)
user.set_password(password)
permission = Permission.objects.get(
codename='DierenWelzijnAdmin | Dier | Can change animal')
user.user_permissions.add(permission)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
username=username,
password=password,
)
user.is_admin = True
user.is_active = True
user.is_staff = True
user.is_superadmin = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser, PermissionsMixin):
first_name = models.CharField(max_length=50, blank=True)
last_name = models.CharField(max_length=50, blank=True)
username = models.CharField(max_length=50, unique=True)
email = models.EmailField(max_length=100, unique=True)
phone_number = models.CharField(max_length=50, blank=True)
# required
date_joined = models.DateTimeField(auto_now_add=True)
last_login = models.DateTimeField(auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_superadmin = models.BooleanField(default=False)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
objects = MyAccountManager()
def full_name(self):
return f"{self.first_name} {self.last_name}"
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, add_label):
return True
And when I start the django app. I don't get any errors.
But when I login with the account with the user permission. I still see the message:
You don’t have permission to view or edit anything.
And the permissions:
Question: how to add permissions for users?
You are not provided the Account
model, but i can imagine the problem:
For example you have app named accounts:
And you want simply to override some functions from User
but you dont want to change User
model. You have:
#accounts.models
from django.contrib.auth import get_user_model
# Register your models here.
User = get_user_model()
class Account(User):
class Meta:
proxy = True
verbose_name = "Account"
def __str__(self):
return f'I override str {self}'
After that you create an admin:
#accounts.admin
from django.contrib import admin
from .models import Account
class AccountAdmin(admin.ModelAdmin):
...
pass
admin.site.register(Account, AccountAdmin)
And after that you add a permission to user:
user, __ = Account.objects.get_or_create(email='n@n.nl', is_staff=True, is_active=True)
content_type = ContentType.objects.get_for_model(Account)
permission = Permission.objects.get(codename='view_account', content_type=content_type)
user.user_permissions.add(permission)
But if you see on content_type.app_label
, you get 'auth'
And AccountAdmin.options.app_label
-> 'accounts'
Problem here is in different app_label and proxy models.
To see you AccountAdmin you should to do:
ct = ContentType.objects.get_or_create(app_label="accounts", model='account')
perm = Permission.objects.get_or_create(codename='view_account', content_type=content_type)
user.user_permissions.add(perm)
I hope it helps.