РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
486 of 818 menu

PermissionDenied

Исключение PermissionDenied относится к модулю django.core.exceptions и используется для сигнализации о том, что текущий пользователь не имеет необходимых прав доступа для выполнения операции. Это исключение автоматически обрабатывается Django и приводит к возврату клиенту HTTP-ответа со статусом 403 (Forbidden). В отличие от исключения Http404, которое говорит о том, что ресурс не найден, PermissionDenied указывает на то, что ресурс существует, но недоступен для данного пользователя.

Исключение принимает один необязательный аргумент - строку с сообщением об ошибке, которая будет передана в ответ. В большинстве случаев это сообщение игнорируется, но может быть полезно для отладки или при кастомной обработке исключений. Исключение можно выбрасывать в любом месте кода, где выполняется проверка прав доступа: в представлениях, в методах моделей, в миксинах для проверки разрешений или в кастомных декораторах. Django также предоставляет встроенные механизмы для автоматического выброса этого исключения, например, декоратор permission_required и миксины для классовых представлений.

При использовании в представлениях, особенно в сочетании с декораторами, исключение PermissionDenied позволяет удобно разделять логику проверки прав и логику обработки данных. Это делает код более чистым и поддерживаемым. Также важно отметить, что исключение можно перехватывать и обрабатывать кастомным образом, например, для перенаправления на страницу входа или для логирования попыток несанкционированного доступа.

Синтаксис

from django.core.exceptions import PermissionDenied raise PermissionDenied("Custom error message")

Пример . Использование в представлении

Проверим, имеет ли пользователь право редактировать статью, и если нет - выбросим исключение:

from django.core.exceptions import PermissionDenied from django.shortcuts import get_object_or_404 from myapp.models import Article def edit_article(request, article_id): article = get_object_or_404(Article, id=article_id) if request.user != article.author: raise PermissionDenied("You are not the author of this article") # Logic for editing the article return render(request, "edit_article.html", {"article": article})

Пример . С декоратором permission_required

Используем встроенный декоратор для проверки наличия конкретного разрешения:

from django.contrib.auth.decorators import permission_required from django.shortcuts import render @permission_required("myapp.change_article", raise_exception=True) def publish_article(request, article_id): # Logic for publishing the article return render(request, "publish_article.html")

Если у пользователя нет разрешения 'myapp.change_article', декоратор автоматически выбросит исключение PermissionDenied.

Пример . В классовых представлениях

Переопределим метод dispatch или используем миксин PermissionRequiredMixin:

from django.contrib.auth.mixins import PermissionRequiredMixin from django.views.generic import UpdateView from django.core.exceptions import PermissionDenied from myapp.models import Article class ArticleUpdateView(PermissionRequiredMixin, UpdateView): model = Article fields = ["title", "content"] permission_required = "myapp.change_article" raise_exception = True class CustomArticleDeleteView(UpdateView): model = Article fields = ["title"] def dispatch(self, request, *args, **kwargs): article = self.get_object() if request.user != article.author: raise PermissionDenied("Only the author can delete this article") return super().dispatch(request, *args, **kwargs)

Пример . Кастомная обработка исключения

Переопределим обработчик для возврата кастомной страницы ошибки:

from django.core.exceptions import PermissionDenied from django.http import HttpResponse from django.template import loader def custom_permission_denied_view(request, exception=None): template = loader.get_template("errors/403.html") context = {"error_message": str(exception) if exception else "Access denied"} return HttpResponse(template.render(context, request), status=403) # In urls.py: # handler403 = custom_permission_denied_view

Пример . В модели

Проверим права доступа в методе модели перед выполнением операции:

from django.core.exceptions import PermissionDenied from django.db import models from django.contrib.auth.models import User class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE) is_published = models.BooleanField(default=False) def publish(self, user): if user != self.author and not user.has_perm("myapp.can_publish_article"): raise PermissionDenied("User cannot publish this article") self.is_published = True self.save()

Результат вызова метода для пользователя без прав:

from myapp.models import Article from django.contrib.auth.models import User article = Article.objects.get(id=1) user = User.objects.get(username="guest") try: article.publish(user) except PermissionDenied as e: print(str(e))

Результат выполнения кода:

"User cannot publish this article"

Смотрите также

  • исключение PermissionDenied,
    которое выбрасывается при отсутствии прав доступа
  • исключение Http404,
    которое выбрасывается, когда ресурс не найден
  • исключение ObjectDoesNotExist,
    которое выбрасывается при отсутствии объекта в базе данных
  • исключение ValidationError,
    которое выбрасывается при ошибках валидации данных
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить