Невозможно получить права на группу с помощью django custom User and Group

Я создаю своего пользовательского пользователя и группу следующим образом:

models.py (приложение myusers)

` из django.db import models из 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",
    )

`

и укажите в файле settings.py: AUTH_USER_MODEL=myusers.User AUTH_GROUP_MODEL=myusers.Group

Все в порядке, но при получении групповых разрешений (a_user.get_all_permissions() или a_user.get_group_permissions()) возникает ошибка: ValueError: Невозможно запросить «a_user»: Должен быть экземпляр «Group». (a_user здесь - экземпляр пользователя) что не так?

Ошибка возврата get_group_permissions().

Структура файла

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

Реализация кода

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'

Шаги тестирования в VS Code

  1. Создайте суперпользователя с помощью команды:

    python manage.py createsuperuser
    
  2. Добавьте нового Group и назначьте права через панель администратора Django.

  3. Протестируйте поведение в Django Shell:

    python manage.py shell
    

Тестовый код

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

Ожидаемый выход

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

Этот код обеспечивает практичную и функциональную реализацию, совместимую с VS Code, и гарантирует, что ваши пользовательские модели Group и User будут работать без проблем. Если у вас есть вопросы по этой теме, пожалуйста, задавайте их. Спасибо Мах Джал!

Проблема решена (после изучения исходного кода django): Поле permissions в модели AbstractGroup должно иметь related_query_name как «group».

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

Спасибо.

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