Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Права доступа
permissions

Права доступа

Встроенные и кастомные permissions, object-level доступ

Права доступа в Django REST Framework

Права доступа (permissions) определяют, имеет ли пользователь право на выполнение запроса. Проверка прав происходит после аутентификации.

#Что такое права доступа

Permissions — механизм DRF, который проверяет, может ли аутентифицированный пользователь выполнить запрошенное действие. Права проверяются:

  • Перед выполнением view
  • Перед сохранением данных (в serializers)

#Настройка прав доступа

Глобальная настройка в settings.py:

REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] }

#Встроенные классы прав доступа

#AllowAny

Разрешает доступ всем пользователям (анонимным и аутентифицированным):

from rest_framework.permissions import AllowAny class PublicView(APIView): permission_classes = [AllowAny] def get(self, request): return Response({'message': 'Public data'})

Использование: Для публичных endpoints (регистрация, логин, публичные данные).

#IsAuthenticated

Требует аутентификации пользователя:

from rest_framework.permissions import IsAuthenticated class ProtectedView(APIView): permission_classes = [IsAuthenticated] def get(self, request): return Response({'user': request.user.username})

Использование: Для всех endpoints, требующих входа пользователя.

#IsAdminUser

Требует, чтобы пользователь был администратором (is_staff=True):

from rest_framework.permissions import IsAdminUser class AdminView(APIView): permission_classes = [IsAdminUser] def get(self, request): return Response({'message': 'Admin only'})

Использование: Для админ-панелей, управления пользователями, системных endpoints.

#DjangoModelPermissions

Проверяет права модели Django (add, change, delete, view):

from rest_framework.permissions import DjangoModelPermissions class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [DjangoModelPermissions]

Требования:

  • queryset должен быть определён в view
  • У пользователя должны быть соответствующие права в Django admin

Маппинг методов к правам:

МетодТребуемое право
POSTadd
PUT/PATCHchange
DELETEdelete
GET (list/retrieve)view (Django 2.1+)

#DjangoModelPermissionsOrAnonReadOnly

Как DjangoModelPermissions, но разрешает GET запросы анонимным пользователям:

from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly class PublicArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [DjangoModelPermissionsOrAnonReadOnly] # GET — всем, POST/PUT/DELETE — только с правами

#IsAuthenticatedOrReadOnly

Разрешает чтение (GET) всем, запись — только аутентифицированным:

from rest_framework.permissions import IsAuthenticatedOrReadOnly class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsAuthenticatedOrReadOnly] # GET — всем, POST/PUT/DELETE — только авторизованным

#Кастомные права доступа

Создание своего класса прав:

from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ Разрешает чтение всем, но редактирование/удаление — только владельцу. """ def has_permission(self, request, view): # Безопасные методы (GET, HEAD, OPTIONS) — всем if request.method in permissions.SAFE_METHODS: return True # Для создания/обновления/удаления — только авторизованным return request.user and request.user.is_authenticated def has_object_permission(self, request, view, obj): # Чтение — всем if request.method in permissions.SAFE_METHODS: return True # Запись — только владельцу return obj.author == request.user

Использование:

class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsOwnerOrReadOnly]

#Методы BasePermission

#has_permission(request, view)

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

def has_permission(self, request, view): # request — текущий запрос # view — экземпляр view # Вернуть True для доступа, False для отказа return request.user.is_staff

#has_object_permission(request, view, obj)

Проверяет право доступа к конкретному объекту:

def has_object_permission(self, request, view, obj): # obj — объект модели, к которому идёт обращение # Вернуть True для доступа к объекту return obj.author == request.user

Важно: has_object_permission вызывается только для detail endpoints (retrieve, update, destroy), не для list.

#Комбинация прав доступа

Можно использовать несколько классов прав одновременно:

from rest_framework.permissions import IsAuthenticated, IsAdminUser class StrictView(APIView): permission_classes = [IsAuthenticated & IsAdminUser] # Требуется и аутентификация, и права админа class RelaxedView(APIView): permission_classes = [IsAdminUser | IsAuthenticated] # Требуется или админ, или просто аутентификация (фактически IsAuthenticated)

Операторы:

  • & (AND) — все условия должны быть истинны
  • | (OR) — хотя бы одно условие истинно
  • ~ (NOT) — инверсия условия

#Object-level permissions

Проверка прав на уровне объекта:

from rest_framework import permissions class IsOwnerOrAdmin(permissions.BasePermission): """Только владелец или админ может редактировать объект""" def has_object_permission(self, request, view, obj): # Админы могут всё if request.user.is_staff: return True # Владелец может редактировать return obj.owner == request.user # В view class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsAuthenticated, IsOwnerOrAdmin]

#Права в сериализаторах

Проверка прав в валидации:

class ArticleSerializer(serializers.ModelSerializer): class Meta: model = Article fields = ['id', 'title', 'content', 'author'] def validate_author(self, value): # Запретить установку другого автора request = self.context['request'] if request.user != value and not request.user.is_staff: raise serializers.ValidationError( "Нельзя создать статью от имени другого пользователя" ) return value

#Права для кастомных действий

from rest_framework import viewsets, permissions from rest_framework.decorators import action from rest_framework.response import Response class ArticleViewSet(viewsets.ModelViewSet): queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = [IsAuthenticated] @action(detail=True, methods=['post'], permission_classes=[IsAdminUser]) def publish(self, request, pk=None): """Только админ может публиковать статьи""" article = self.get_object() article.is_published = True article.save() return Response({'status': 'published'}) @action(detail=True, methods=['post']) def like(self, request, pk=None): """Любой авторизованный пользователь может лайкнуть""" article = self.get_object() article.likes.add(request.user) return Response({'status': 'liked'})

#Best Practices

  1. Используйте IsAuthenticated по умолчанию — безопаснее, чем разрешать всё
  2. Object-level permissions для контроля доступа к конкретным объектам
  3. SAFE_METHODS для разрешения чтения всем — ('GET', 'HEAD', 'OPTIONS')
  4. Комбинируйте права через & и | для гибкой логики
  5. Тестируйте права — проверяйте доступ для разных типов пользователей
  6. Документируйте требования — указывайте в документации API, какие права нужны

Далее: Троттлинг