Когда речь заходит о правах доступа, прежде всего мы должны задать себе вопрос: кто имеет доступ к чему и зачем? Django Admin предоставляет мощный встроенный механизм контроля доступа, который позволяет распределять права между различными пользователями и группами. Это важно не только для обеспечения безопасности, но и для предотвращения ошибок, связанных с человеческим фактором.
Что такое права доступа в Django?
Права доступа в Django — это способ управления действиями пользователей. Django из коробки предоставляет несколько базовых уровней прав для каждой модели:
add: позволяет добавлять новые записи.change: позволяет изменять существующие записи.delete: позволяет удалять записи.view: позволяет просматривать записи (добавлено в Django 2.1).
Эти права назначаются пользователям или группам пользователей, что позволяет гибко управлять доступом к данным.
Управление встроенными правами
В Django каждый пользователь может быть связан с одной или несколькими группами. Группы — это инструмент для упрощения управления правами пользователей: вы создаёте группу (например, "Редакторы") и назначаете ей соответствующие права. Все пользователи, входящие в группу, автоматически наследуют её права.
Определение прав для пользователей
Пример: допустим, у нас есть модель Post, представляющая записи в блоге. Пользователь с правами add может создавать новые посты, но не редактировать существующие, если у него нет права change.
Пример кода для проверки прав в представлениях:
from django.contrib.auth.decorators import permission_required
@permission_required('blog.add_post', raise_exception=True)
def create_post(request):
# Код для создания поста
pass
Назначение прав в админ-зоне
Интерфейс Django Admin позволяет вручную предоставлять права для пользователей. Это делается в разделе "Пользователи" и "Группы". Например:
- Перейдите в админ-зону проекта.
- Выберите раздел "Группы".
- Создайте группу "Редакторы".
- Свяжите с группой права
addиchangeдля моделиPost.
Кастомные права
Иногда встроенных прав недостаточно. Например, вам может понадобиться право на "публикацию статьи". Django позволяет создавать кастомные права, добавив их в класс модели.
Пример создания кастомного права:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
is_published = models.BooleanField(default=False)
class Meta:
permissions = [
("can_publish", "Can publish posts"),
]
Теперь у нас есть новое право can_publish, которое можно назначать пользователям. Для его проверки в коде мы можем использовать метод has_perm.
Пример:
from django.http import HttpResponseForbidden
def publish_post(request, post_id):
if not request.user.has_perm('blog.can_publish'):
return HttpResponseForbidden("У вас нет прав на публикацию.")
# Логика публикации поста
pass
Ограничение доступа в админ-зоне
Django Admin также позволяет кастомизировать доступ к моделям и их действиям. Для этого мы можем переопределить методы ModelAdmin, такие, как has_add_permission, has_change_permission, has_delete_permission и has_view_permission.
Допустим, мы хотим разрешить удаление записей только суперпользователям. Вот как это можно сделать:
from django.contrib import admin
class PostAdmin(admin.ModelAdmin):
def has_delete_permission(self, request, obj=None):
return request.user.is_superuser
Может возникнуть ситуация, когда пользователи могут изменять или удалять только те записи, которые они сами создали. Здесь на помощь приходит объект request.
class PostAdmin(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
if obj is None: # Показываем список всех объектов
return True
return obj.author == request.user
def has_delete_permission(self, request, obj=None):
if obj is None: # Показываем список всех объектов
return True
return obj.author == request.user
Расширение возможностей прав доступа
Иногда нам нужно реализовать сложную логику управления доступом, которая выходит за рамки стандартных возможностей Django.
Сигналы Django позволяют автоматически назначать права пользователям. Например, мы хотим, чтобы автор поста автоматически получал все права на него.
Пример с использованием сигнала post_save:
from django.db.models.signals import post_save
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.dispatch import receiver
from .models import Post
@receiver(post_save, sender=Post)
def assign_permissions(sender, instance, created, **kwargs):
if created:
content_type = ContentType.objects.get_for_model(Post)
permissions = Permission.objects.filter(content_type=content_type)
for perm in permissions:
instance.author.user_permissions.add(perm)
Теперь при создании нового поста его автор автоматически получит права на управление этим постом.
Управление группами пользователей
Для управления доступом удобнее всего использовать группы. Группы позволяют объединять пользователей с одинаковыми правами и управлять ими централизованно.
Пример добавления пользователя в группу:
from django.contrib.auth.models import Group
def add_user_to_group(user, group_name):
group, created = Group.objects.get_or_create(name=group_name)
group.user_set.add(user)
С помощью этого кода мы можем легко добавить нового пользователя в существующую группу.
Практическое задание
- Создайте модель
Articleс полями:title,content,author,is_published. - Добавьте кастомное право
can_publishв модель. - Настройте админ-зону так, чтобы только пользователи с правом
can_publishмогли публиковать статьи. - Оставьте возможность изменения и удаления статей только их авторам.
- В админ-зоне добавьте фильтры по полю
authorи индикатор публикацииis_published.
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'is_published')
list_filter = ('author', 'is_published')
def has_change_permission(self, request, obj=None):
if obj is None:
return True
return obj.author == request.user
def has_delete_permission(self, request, obj=None):
if obj is None:
return True
return obj.author == request.user
На этом этапе у вас уже есть все инструменты, чтобы не только управлять доступом в админ-зоне, но и делать её максимально функциональной и безопасной. Как вы заметили, права доступа в Django — это не только про безопасность, но и про удобство для конечного пользователя. Впереди вас ждут новые горизонты! 🚀
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ