Метод has_change_permission

Метод has_change_permission применяется к экземпляру ModelAdmin и определяет, может ли пользователь изменять объекты данной модели в административной панели. Метод вызывается при отображении списка объектов, при переходе на страницу редактирования и при попытке сохранения изменений. Он принимает объект запроса и опционально конкретный объект модели, что позволяет гибко настраивать права на уровне отдельных записей.

Синтаксис

pythonclass MyModelAdmin(admin.ModelAdmin):
  def has_change_permission(self, request, obj=None):
    # логика проверки
    return True или False

Метод должен возвращать True, если пользователь может изменять объект, и False в противном случае. Параметр obj принимает экземпляр модели или None при проверке общей возможности изменения для всей модели.

Пример . С проверкой группы пользователей

Разрешим изменение объектов только пользователям, входящим в группу "content_managers":

pythonfrom django.contrib import admin
from django.contrib.auth.models import Group
from myapp.models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
  list_display = ['title', 'status']

  def has_change_permission(self, request, obj=None):
    # Суперпользователи всегда имеют доступ
    if request.user.is_superuser:
      return True

    # Проверяем принадлежность к группе
    content_group = Group.objects.get(name='content_managers')
    if content_group in request.user.groups.all():
      return True

    return False

Теперь только суперпользователи и участники группы "content_managers" могут редактировать статьи. Остальные пользователи увидят, что кнопка "Изменить" отсутствует или недоступна.

Пример . С ограничением по статусу объекта

Запретим изменение объектов, которые уже опубликованы, чтобы избежать случайной правки важных материалов:

pythonfrom django.contrib import admin
from myapp.models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
  list_display = ['title', 'status']
  readonly_fields = ['status']

  def has_change_permission(self, request, obj=None):
    # Если объект не передан - разрешаем (проверка списка объектов)
    if obj is None:
      return True

    # Запрещаем изменение опубликованных статей
    if obj.status == 'published':
      return False

    return True

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

python"Change permission for draft article: True"
"Change permission for published article: False"

Теперь администратор не может изменять опубликованные статьи, но может работать с черновиками. Поле status добавлено в readonly_fields для наглядности.

Пример . С комбинированной проверкой

Создадим более сложную логику: разрешим изменение только авторам их собственных статей или менеджерам, но с ограничением на изменение статуса публикации:

pythonfrom django.contrib import admin
from django.contrib.auth.models import Group
from myapp.models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
  list_display = ['title', 'author', 'status']
  fields = ['title', 'content', 'status']

  def has_change_permission(self, request, obj=None):
    # Суперпользователи имеют полный доступ
    if request.user.is_superuser:
      return True

    # Для проверки списка объектов
    if obj is None:
      return True

    # Автор может изменять свои статьи
    if obj.author == request.user:
      return True

    # Менеджеры могут изменять любые статьи, но не статус
    manager_group = Group.objects.get(name='managers')
    if manager_group in request.user.groups.all():
      # Запоминаем ограничение в запросе для save_model
      request._status_change_restricted = True
      return True

    return False

В этом примере авторы имеют полный доступ к своим статьям, а менеджеры - ко всем, но с ограничением на изменение статуса (это можно дополнительно обработать в методе save_model).

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

  • метод has_add_permission,
    который проверяет право на добавление объектов
  • метод has_delete_permission,
    который проверяет право на удаление объектов
  • метод get_queryset,
    который фильтрует объекты для отображения в админке
  • метод save_model,
    который обрабатывает сохранение объекта и может дополнять проверку прав