Django-guardian. Добавляем управление разрешениями на уровне объектов

28 Май 2021 , 332

В предыдущей статье мы рассматривали разрешения(permissions), которые предоставляются из фреймворка Django. Они входят в пакет django.contrib.auth. Рассмотрели какие 4 разрешения Django создает для каждой модели по умолчанию.Рассмотрели как эти разрешения можно задавать определенным пользователям и назначать эти разрешения группам. Рассмотрели , как можно в модели определять другие специфические разрешения и как их создавать программно. Но все эти разрешения на уровне модели.

Что это значит ?

Допустим , когда мы создаем модель Post , то Django наряду с другими разрешениями по умолчанию создает разрешение change_post. И допустим, у нас есть пользователь Василий и мы ему задаем разрешение change_post. И теперь он может изменять все статьи , так как у него есть такое разрешение. А что если мы хотим дать разрешение на редактирование только определенным статьям (объектам модели Post ). Допустим есть четыре поста(объекта) и мы хотим дать Василию разрешение на редактирование первой и третьей статьи, а остальные статьи он не может редактировать. Вот для решения таких задач(упраление разрешениями на уровне объектов) мы и будем использовать замечательную библиотеку django-guardian

Django-guardian. Добавляем управление разрешениями на уровне объектов

Создадим новый проект blogproject. И установим библиотеку django-guardian


pip install django-guardian

Подключим django_guardian в наш проект в файле settings.py.Также в этом файле добавим бэкенды для авторизации , которые используются для работы django_guardian


INSTALLED_APPS = (
 #другие приложения
 'guardian',
)

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', # Этот бэкенд Django использует по умолчанию
    'guardian.backends.ObjectPermissionBackend', # А это  бэкенд django_guardian
)

После применения миграций командой:


python manage.py migrate

Мы в базе данных увидим две таблицы , которые создал пакет django_guardian

Это таблицы guardian_userobjectpermission и guardian_groupobjectpermission

Давайте создадим приложение blog и внутри модель Post


python manage.py startapp blog

Файл models.py


from django.db import models


class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()

    def __str__(self):
        return self.title


Приложение blog подключим к INSTALLED_APP


INSTALLED_APPS = (
 #другие приложения
 'guardian',
 'blog',
)

Создадим миграции и применим их


python manage.py makemigrations
python manage.py migrate

Теперь мы можем задавать разрешения либо программно , либо через административную панель Django. Давайте реализуем это через административную панель Django и покажем как каждому посту можно указать пользователя , который может редактировать этот пост.

В файле admin.py напишем такой код:


from django.contrib import admin
from blog.models import Post
from guardian.admin import GuardedModelAdmin


class PostAdmin(GuardedModelAdmin):
    list_display = ('title',)


admin.site.register(Post, PostAdmin)

Добавляем первый пост и для пользователя Василия мы разрешим его редактирование(

Как вы видите , для пользователя Василий для объекта первый пост мы задали разрешение can_change_post

Это все можно сделать и программно. Давайте добавим третью статью и для пользователя Василия укажем , разрешение change_post


from django.contrib.auth.models import User
from guardian.models import UserObjectPermission
vasiliy = User.objects.get(username='vasiliy')
from blog.models import Post
third_post = Post.objects.create(title='Third post', content='this is third post')
#Ключевой момент , присваиваем разрешение change_post , пользователю vasiliy, для третьего поста 
UserObjectPermission.objects.assign_perm('change_post', vasiliy, obj=third_post)

#Проверяем , есть ли такое разрешение 
vasiliy.has_perm('change_post', third_post)
True


Заключение

В данной статье я постарался показать как можно задавать разрешения отдельным объектам и управлять ими через административную панель или программным способом. С помощью замечательной библиотеки django-guardian это все реализуется очень легко.

comments powered by Disqus

Подписка

Подпишитесь на наш список рассылки, чтобы получать обновления из блога

Рубрики

Теги