JavaRush /Курси /Модуль 3: Django /Робота з правами доступу в адмін-зоні

Робота з правами доступу в адмін-зоні

Модуль 3: Django
Рівень 11 , Лекція 8
Відкрита

Коли мова йде про права доступу, перш за все ми маємо поставити собі питання: хто має доступ до чого і навіщо? 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 дозволяє вручну надавати права для користувачів. Це робиться в розділі "Користувачі" та "Групи". Наприклад:

  1. Перейдіть в адмін-зону проєкту.
  2. Виберіть розділ "Групи".
  3. Створіть групу "Редактори".
  4. Зв'яжіть з групою права 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)

За допомогою цього коду ми можемо легко додати нового користувача в існуючу групу.

Практичне завдання

  1. Створіть модель Article з полями: title, content, author, is_published.
  2. Додайте кастомне право can_publish у модель.
  3. Налаштуйте адмін-зону так, щоб тільки користувачі з правом can_publish могли публікувати статті.
  4. Залиште можливість змінення та видалення статей тільки їх авторам.
  5. В адмін-зоні додайте фільтри за полем 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 — це не лише про безпеку, але й про зручність для кінцевого користувача. Попереду вас чекають нові горизонти! 🚀

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ