Can not get group permissions by django custom User and Group

I create my custom user and group as below:

models.py (myusers app)

` from django.db import models from django.contrib.auth.models import AbstractUser, GroupManager, Permission

class AbstractGroup(models.Model):
    name = models.CharField(_("name"), max_length=150, unique=True)
    permissions = models.ManyToManyField(
        Permission,
        verbose_name=_("permissions"),
        blank=True,
        related_name="fk_group_permission",
    )

    objects = GroupManager()

    def __str__(self):
        return self.name

    def natural_key(self):
        return (self.name,)

    class Meta:
        verbose_name = _("group")
        verbose_name_plural = _("groups")
        abstract = True

class Group(AbstractGroup):
    is_active = models.BooleanField(_("Is Active"), default=True)

class User(AbstractUser):
    groups = models.ManyToManyField(
        Group,
        verbose_name=_("groups"),
        blank=True,
        help_text=_(
            "The groups this user belongs to. A user will get all permissions "
            "granted to each of their groups."
        ),
        related_name="user_set",
        related_query_name="user",
    )

`

and point in settings.py: AUTH_USER_MODEL=myusers.User AUTH_GROUP_MODEL=myusers.Group

All is ok but when get group permissions (a_user.get_all_permissions() or a_user.get_group_permissions()) raise error: ValueError: Cannot query “a_user”: Must be “Group” instance. (a_user here is the user user instance) what is wrong?

The get_group_permissions() return error.

File Structure

myproject/
├── manage.py
├── myproject/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   ├── wsgi.py
├── myusers/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── views.py
│   ├── tests.py
│   ├── migrations/
│       ├── __init__.py

Code Implementation

1. myusers/models.py

from django.contrib.auth.models import AbstractUser, GroupManager, Permission
from django.db import models
from django.utils.translation import gettext_lazy as _


class AbstractGroup(models.Model):
    name = models.CharField(_("name"), max_length=150, unique=True)
    permissions = models.ManyToManyField(
        Permission,
        verbose_name=_("permissions"),
        blank=True,
        related_name="fk_group_permission",
    )

    objects = GroupManager()

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _("group")
        verbose_name_plural = _("groups")
        abstract = True


class Group(AbstractGroup):
    is_active = models.BooleanField(_("Is Active"), default=True)


class User(AbstractUser):
    groups = models.ManyToManyField(
        Group,
        verbose_name=_("groups"),
        blank=True,
        help_text=_(
            "The groups this user belongs to. A user will get all permissions "
            "granted to each of their groups."
        ),
        related_name="user_set",
        related_query_name="user",
    )

    def get_group_permissions(self, obj=None):
        if not self.is_active or self.is_anonymous:
            return set()
        permissions = Permission.objects.filter(group__user_set=self).values_list(
            "content_type__app_label", "codename"
        )
        return {"%s.%s" % (ct, name) for ct, name in permissions}

    def get_all_permissions(self, obj=None):
        if not self.is_active or self.is_anonymous:
            return set()
        user_permissions = self.user_permissions.all().values_list(
            "content_type__app_label", "codename"
        )
        group_permissions = self.get_group_permissions()
        return {
            "%s.%s" % (ct, name) for ct, name in user_permissions
        } | group_permissions

2. myproject/settings.py

AUTH_USER_MODEL = 'myusers.User'
AUTH_GROUP_MODEL = 'myusers.Group'

Steps to Test in VS Code

  1. Create a superuser using the command:

    python manage.py createsuperuser
    
  2. Add a new Group and assign permissions via the Django admin panel.

  3. Test the behavior in Django Shell:

    python manage.py shell
    

Test Code

from myusers.models import User, Group
from django.contrib.auth.models import Permission

# Create a test group
group = Group.objects.create(name="Test Group")
permission = Permission.objects.get(codename="add_user")  # Example permission
group.permissions.add(permission)

# Create a test user
user = User.objects.create_user(username="testuser", password="testpassword")
user.groups.add(group)

# Fetch group permissions
print(user.get_group_permissions())
print(user.get_all_permissions())

Expected Output

{'auth.add_user'}  # Group-level permission
{'auth.add_user'}  # All permissions (group + user-level)

This code provides a practical and functional implementation compatible with VS Code and ensures your custom Group and User models work seamlessly. If you have any questions regarding this issue, please feel free to ask. Thank you Mah Jal!

Вернуться на верх