Django-guardian. Добавляем управление разрешениями на уровне объектов
В предыдущей статье мы рассматривали разрешения(permissions), которые предоставляются из фреймворка Django. Они входят в пакет django.contrib.auth. Рассмотрели какие 4 разрешения Django создает для каждой модели по умолчанию.Рассмотрели как эти разрешения можно задавать определенным пользователям и назначать эти разрешения группам. Рассмотрели , как можно в модели определять другие специфические разрешения и как их создавать программно. Но все эти разрешения на уровне модели.
Что это значит ?
Допустим , когда мы создаем модель Post , то Django наряду с другими разрешениями по умолчанию создает разрешение change_post. И допустим, у нас есть пользователь Василий и мы ему задаем разрешение change_post. И теперь он может изменять все статьи , так как у него есть такое разрешение. А что если мы хотим дать разрешение на редактирование только определенным статьям (объектам модели Post ). Допустим есть четыре поста(объекта) и мы хотим дать Василию разрешение на редактирование первой и третьей статьи, а остальные статьи он не может редактировать. Вот для решения таких задач(упраление разрешениями на уровне объектов) мы и будем использовать замечательную библиотеку 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 это все реализуется очень легко.