Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Работа с правами доступа в Django
  • Работа с per-object правами доступа
  • Работа с правами доступа в Django Rest Framework
  • Паттерны написания кода для прав доступа
  • Защита эндпоинтов правами доступа
  • Фильтрация Queryset'ов на основе прав доступа

...

(warning) Права доступа всегда привязаны к какой-либо сущности.

Создание (определение) прав доступа

Например: у нас есть сущность "Общежитие". Логически подумав, мы пришли к тому, что хотим:

...

(warning) Любое право доступа обязательно характеризуется словами "для некоторых пользователей". Если такого требования нет - достаточно флажка в модели (если хотим скрывать или показывать общежитие всем пользователям одновременно - то для этого достаточно поля "is_hidden" типа BooleanField в модели общежития).


Для того, чтобы определить права доступа для сущности, мы используем атрибут permissions у Meta-класса модели.

Сам пермишн мы задаём в виде кортежа из 2х элементов:

1) Кодовое название пермишна (должно быть уникально среди всех пермишнов всех сущностей в модуле) 

2) "Человеческое" название пермишна (которое затем будет отображаться в админке)

Image Added


За создание непосредственно объектов Permissions отвечает management-команда migrate. Она проходит по всем permissions и создаёт нужные строчки в БД.

Info

Права доступа для сущности определяем с помощью атрибута permissions в Meta-классе модели. Конкретные строчки в БД формируются в процессе выполнения миграций.

P.S. Можно (но не рекомендуется) программно создавать пермишны. Это описано в документации по ссылке: https://docs.djangoproject.com/en/4.2/topics/auth/default/#programmatically-creating-permissions 

Присвоение прав доступа группам/пользователям

Самый простой способ присвоить право доступа - сделать это через админку, в панели редактирования группы (или пользователя).

Image Added

(warning) В проекте mipt.tech нельзя выдавать права конкретным пользователям - это приводит к путанице и сложности контроля за выданными правами. Все права выдаются только группам! 

Программно добавить права доступа также можно, например, так (перед использованием посоветуйтесь, маловероятно, что вам это понадобится):

Code Block
languagepy
titleПример кода
linenumberstrue
collapsetrue
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

Code Block
languagepy
titleПример кода
linenumberstrue
collapsetrue
if some_user.has_perm("rooms.object_level_view_dormitory"):
    echo "Horaay!"

Работа с правами доступа в Django rest framework

...