为什么 `user.has_perm(Model, obj)` return False 虽然 `user.has_perm(Model)` return 是 True?
Why does `user.has_perm(Model, obj)` return False although `user.has_perm(Model)` returns True?
在刚刚使用 django-admin startproject
和 ./manage.py startapp
创建的 Django 项目和应用程序中,我创建了这个模型:
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()
应该如何工作?这在某处记录了吗?
has_perm()
API 旨在与模型级权限(第二个参数为 None
)和对象级权限一起使用。但是,由个人 authentication backends 决定支持什么。
在 Django 的默认情况下 ModelBackend
有 no support for object-level permissions:
Django’s permission framework has a foundation for object permissions, though there is no implementation for it in the core. That means that checking for object permissions will always return False
.
这在ModelBackend
documentation中也有注明。
请注意,此处后端必须 return False
,因为各个后端的结果本质上是通过“或”运算在一起的。如果这个后端 returned True
就不可能尊重来自其他后端的更细粒度的结果。
还有 个实现对象级权限的后端,django-guardian being perhaps the best known. See how it documents has_perm()
:
Main difference between Django's ModelBackend
is that we can pass obj
instance here.
在刚刚使用 django-admin startproject
和 ./manage.py startapp
创建的 Django 项目和应用程序中,我创建了这个模型:
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()
应该如何工作?这在某处记录了吗?
has_perm()
API 旨在与模型级权限(第二个参数为 None
)和对象级权限一起使用。但是,由个人 authentication backends 决定支持什么。
在 Django 的默认情况下 ModelBackend
有 no support for object-level permissions:
Django’s permission framework has a foundation for object permissions, though there is no implementation for it in the core. That means that checking for object permissions will always return
False
.
这在ModelBackend
documentation中也有注明。
请注意,此处后端必须 return False
,因为各个后端的结果本质上是通过“或”运算在一起的。如果这个后端 returned True
就不可能尊重来自其他后端的更细粒度的结果。
还有 个实现对象级权限的后端,django-guardian being perhaps the best known. See how it documents has_perm()
:
Main difference between Django's
ModelBackend
is that we can passobj
instance here.