Вся логика работы прав доступа сосредоточена в модуле django.contrib.auth через модель Permission и методы для работы с ней.
Модель Permission имеет Many-to-many связь с моделью Group (через поле permissions в модели Group), это позволяет назначать конкретные права группам.
Модель Permission имеет Many-to-many связь с моделью User (через поле user_permissions в модели User), это позволяет назначать конкретные права отдельным пользователям.
Наличие права X у пользователя/группы Y фактически означает наличие соответствующей записи в табличке ManyToMany-связей.
Права доступа - это строчки в таблице прав доступа. Назначение права доступа пользователю - это соответствие между строкой в таблице прав доступа, и строкой в таблице юзеров (или групп) |
Напрямую с правами доступа как моделями и/или записями в БД мы не работаем. Для работы с правами доступа в Django предусмотрен специальный "синтаксический сахар".
Права доступа всегда привязаны к какой-либо сущности.
Например: у нас есть сущность "Общежитие". Логически подумав, мы пришли к тому, что хотим:
1) Скрывать общежитие для некоторых пользователей
2) Давать некоторым пользователям управлять общежитием (например, изменять контент находящихся в нём помещений).
Любое право доступа обязательно характеризуется словами "для некоторых пользователей". Если такого требования нет - достаточно флажка в модели (если хотим скрывать или показывать общежитие всем пользователям одновременно - то для этого достаточно поля "is_hidden" типа BooleanField в модели общежития).
Для того, чтобы определить права доступа для сущности, мы используем атрибут permissions у Meta-класса модели.
Сам пермишн мы задаём в виде кортежа из 2х элементов:
1) Кодовое название пермишна (должно быть уникально среди всех пермишнов всех сущностей в модуле)
2) "Человеческое" название пермишна (которое затем будет отображаться в админке)

За создание непосредственно объектов Permissions отвечает management-команда migrate. Она проходит по всем permissions и создаёт нужные строчки в БД.
Права доступа для сущности определяем с помощью атрибута permissions в Meta-классе модели. Конкретные строчки в БД формируются в процессе выполнения миграций. |
P.S. Можно (но не рекомендуется) программно создавать пермишны. Это описано в документации по ссылке: https://docs.djangoproject.com/en/4.2/topics/auth/default/#programmatically-creating-permissions
Самый простой способ присвоить право доступа - сделать это через админку, в панели редактирования группы (или пользователя).

В проекте mipt.tech нельзя выдавать права конкретным пользователям - это приводит к путанице и сложности контроля за выданными правами. Все права выдаются только группам!
Программно добавить права доступа также можно, например, так (перед использованием посоветуйтесь, маловероятно, что вам это понадобится):
from rooms.models import Dormitory
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(Dormitory) # Получаем ContentType для модели Dormitory
permission = Permission.objects.get( # Получаем объект Permission, используя кодовое название и Content Type
codename="object_level_view_dormitory",
content_type=content_type,
)
some_user.user_permissions.add(permission) # Используя атрибут user_permissions объекта User с типом ManyToManyField, добавляем новый пермишн
some_group.permissions.add(permission) |
Проверять наличие права доступа у пользователя можно с помощью метода has_perm у класса User. Семантика: has_perm("<app label>.<permission codename>")
https://docs.djangoproject.com/en/4.2/ref/contrib/auth/#django.contrib.auth.models.User.has_perm
if some_user.has_perm("rooms.object_level_view_dormitory"):
echo "Horaay!" |