Коли мова йде про права доступу, перш за все ми маємо поставити собі питання: хто має доступ до чого і навіщо? 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, яке можна призначати користувачам. Для його перевірки в коді ми можемо використовувати метод 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 — це не лише про безпеку, але й про зручність для кінцевого користувача. Попереду вас чекають нові горизонти! 🚀
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ