Невозможно получить права на группу с помощью 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
Создайте суперпользователя с помощью команды:
python manage.py createsuperuser
Добавьте нового
Group
и назначьте права через панель администратора Django.Протестируйте поведение в 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",
)
...
Спасибо.