Почему `user.has_perm (Model, obj)` возвращает False, а `user.has_perm (Model)` возвращает True? - PullRequest
1 голос
/ 23 марта 2019

В Django-проекте и приложении, только что созданном с django-admin startproject и ./manage.py startapp, я создал эту модель:

class Book(models.Model):
    author = models.CharField(max_length=50)

Затем я запускаю этот код с ./manage.py shell:

from django.contrib.auth.models import Permission, User
from django.test import TestCase
from myapp.models import Book

myuser = User.objects.create_user(username="myuser")
myuser.user_permissions.add(Permission.objects.get(codename="change_book"))

mybook = Book(author="Joe Author")
mybook.save()

myuser.has_perm("myapp.change_book"))  # The result is True
myuser.has_perm("myapp.change_book", mybook))  # The result is False

Почему это?Пользователь имеет разрешение на редактирование mybook, не так ли?Как has_perm() должен работать?Это где-то задокументировано?

1 Ответ

2 голосов
/ 24 марта 2019

API has_perm() предназначен для работы как с разрешениями на уровне модели (второй параметр None), так и с разрешениями на уровне объектов. Однако для определения того, что поддерживать, требуется индивидуальный аутентификационный бэкэнд .

В случае Django по умолчанию ModelBackend не поддерживает разрешения на уровне объекта :

Структура разрешений Django имеет основу для разрешений объектов, хотя в ядре нет реализации для нее. Это означает, что проверка прав доступа к объекту всегда вернет False.

Это также отмечено в ModelBackend документации .

Обратите внимание, что бэкэнд должен возвращать False здесь, так как результаты от отдельных бэкэндов, по сути, объединены в OR. Если этот бэкэнд вернул True, было бы невозможно учесть более детальные результаты других бэкэндов.

И являются бэкэндами, которые реализуют разрешения на уровне объектов, django-guardian является, пожалуй, самым известным. Посмотрите, как это документы has_perm():

Основное различие между ModelBackend в Django заключается в том, что мы можем передать obj экземпляр здесь.

...