Django permissions. Управление правами доступа
Django предоставляет из коробки систему аутентификации и авторизации(permission) пользователей. Эта система позволяет проверять учетные данные пользователей и определять права доступа для пользователей. Ввод логина и пароля - это аутентификация пользователей , а права доступа на редактирование записей , создание новых и удаление - это уже авторизация. Поэтому,с помощью permissions мы указываем какие действия могут выполнять пользователи на сайте , а к каким запрещен доступ.
После создания нового проекта на Django , то в файле settings.py вы можете увидеть , что система аутентификации django.contrib.auth уже включена . Также по умолчанию включена система типов контента Django django.contrib.contenttypes, которая позволяет связывать разрешения(permissons) с создаваемыми вами моделями.
'INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth', #Система аутентификации
'django.contrib.contenttypes', # Cистема типов контента
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
С этими настройками после выполнения команды python manage.py migrate
в базе данных создаются необходимые таблицы для моделей связанных с аутентификацией и с разрешениями(permissions)
Таким образом , Django имеет встроенную систему разрешений(permissions). Эта система позволяет назначать разрешения конкретным пользователям и группам пользователей.
Эту систему использует Django admin
Django по умолчанию для модели создает 4 разрешения. Давайте посмотрим это на примере и потом подробно обсудим все 4 разрешения предоставляемых для модели по умолчанию
Создадим в нашем проекте новое приложение(application)
python manage.py startapp blog
В файле models.py создадим модель Post
from django.db import models
class Post(models.Model):
name = models.CharField(max_length=255)
content = models.TextField()
def __str__(self):
return self.name
Создадим миграции
После выполнения миграции в базе данных создается таблица blog_post. Также в таблицу auth_permission добавляются четыре разрешения(permissions) ассоциированных с моделью Post.
Django для нашей модели Post после выполнения миграций создала четыре разрешения
- Разрешение add(в нашем случае add_post) позволяет пользователям добавлять экземпляры модели.
- Разрешение change(в нашем случае change_post) позволяет пользователям редактировать экземпляры модели
- Разрешение delete(в нашем случае delete_post) позволяет пользователям удалять экземпляры модели
- Разрешение view(в нашем случае view_post) позволяет пользователям просматривать экземпляры данной модели. Это разрешение появилось в Django 2.1
Имена разрешений следуют особому соглашению об именах:
В нашем случае для модели Post разрешения будут выглядеть следующим образом:
- blog.add_post , где blog - это имя приложения(app), add - это действие(action), а post - это название модели(modelname)
- blog.change_post , где blog - это имя приложения(app), change - это действие(action), а post - это название модели(modelname)
- blog.delete_post , где blog - это имя приложения(app), delete - это действие(action), а post - это название модели(modelname)
- blog.view_post , где blog - это имя приложения(app), view - это действие(action), а post - это название модели(modelname)
В админке Django , если мы зайдем под правами суперпользователя , то мы можем назначать эти права определенным пользователям.
Также мы можем создать группу . Этой группе добавить права(разрешения). И у всех пользователей , которые будут принадлежать этой группе будут соответствующие права.
К примеру , мы можем создать группу moderators и этой группе добавим все разрешения на добавления , редактирования , просмотра и удаления постов. И все пользователи , которых мы добавим группу moderators будут иметь возможность в админке добавлять , редактировать , просматривать и удалять посты.
Разрешения пользователям мы можем задавать не только в административной панели Django, но также программно. Мы можем управлять разрешениями следующими методами:
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
В приложении blog для модели Blog создадим вьюху для добавления поста. Добавлять пост может только пользователь у которого будет разрешение add_post
from django.contrib.auth.mixins import PermissionRequiredMixin
class CreatePostView(PermissionRequiredMixin, CreateView):
permission_required = 'blog.add_post'
model = Post
fields = ('name', 'content')
Здесь мы используем миксин PermissionRequiredMixin , потому что мы используем CreateView для создания нового объекта модели поста. У миксина PermissionRequiredMixin в поле permission_required мы задаем разрещение : blog.add_post.Если пользователь аутентифицирован , но при этом у него нет разрешения добавлять посты , то ему будет отказано в доступе к этой вьюхе и будет возвращен код 403(Доступ воспрещен). А если у него будет разрещение blog.add_post , то он сможет создать новый пост
Если бы мы использовали вьюху создания поста в функциональном стиле , то для разграничения доступа , мы могли использовать декоратор permission_required
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required('blog.add_post', raise_exception=True)
def add_post(request):
#Код для добавления нового поста
return render(request)
Также мы можем проверять есть ли у данного пользователя определенное разрешение или нет , с помощью метода has_perm
def add_post(request):
#Проверяем есть ли у данного пользователя разрешение для добавления поста
#Если такого разрешения нет, то выкидываем исключение PermissionDenied
if not request.user.has_perm('blog.add_post'):
raise PermissionDenied
# Бизнес-логика для добавления поста
Для неаутентифицированного пользователя AnonymousUser метод has_perm всегда будет возвращать false.
Заключение
В данной статье мы рассмотрели Django permissions , которые позволяют разграничивать доступ к объектам. Это очень мощная штука , которая позволяет нам легко ограничивать доступ к добавлению,редактированию, удалению объектов разных моделей.