Django 规则对象权限

6

我正在尝试使用django rules在Django和Django管理界面中配置对象权限。

现在,当我添加权限规则时,它们将始终仅使用第一个参数调用,但对象始终为None。

例如,如果我创建了这个谓词:

@rules.predicate
def is_book_author(user, book):
    return book.author == user

然后将其添加到Django权限集中:

rules.add_perm('books.view_book', is_book_author)

现在当我使用用户登录管理界面时,is_book_author将会以用户和空对象作为参数进行调用。它将会被多次调用(每个对象调用一次),但对象总是为空。我正在使用Django 2.1.1和Python 3.7的规则2.0.0。有没有什么想法,是否我做错了什么,或者如何配置Django以调用单个对象的谓词?

那时候,这本书还不存在。add_book 是添加书籍的权限,而不是“保存”书籍的权限。我认为你应该在表单中处理这个问题(甚至只需“注入”用户),以便他/她根本无法添加其他数据。 - Willem Van Onsem
谢谢您的评论,但我遇到了所有4个权限的问题。我在问题中将add_book替换为view_book权限以进行澄清。 - Tigerware
1
@BluE 我正在尝试解决你的问题,但是在我的机器上一切都正常。我使用了testapp进行调试,仍然无法复现你的问题。你能提供使用ObjectPermissionsModelAdminadd_perm谓词的完整文件吗? 同时请查看 https://github.com/dfunckt/django-rules/blob/v2.0.0/tests/testapp/rules.py 尝试将你的代码与存储库中的代码进行比较。 - Kamil Niski
@KamilNiski 我会在今天下班后更新问题,添加所请求的信息。快速提问:您在尝试示例时是否使用相同的Django版本? - Tigerware
是的,我使用了你指定的完全相同版本的库。 - Kamil Niski
@BluE 有什么消息吗?你能找到问题了吗? - Kamil Niski
1个回答

8

django-rules文档所述:

Django Admin does not support object-permissions, in the sense that it will never ask for permission to perform an action on an object, only whether a user is allowed to act on (any) instances of a model.

If you'd like to tell Django whether a user has permissions on a specific object, you'd have to override the following methods of a model's ModelAdmin:

has_view_permission(user, obj=None)
has_change_permission(user, obj=None)
has_delete_permission(user, obj=None)

rules comes with a custom ModelAdmin subclass, rules.contrib.admin.ObjectPermissionsModelAdmin, that overrides these methods to pass on the edited model instance to the authorization backends, thus enabling permissions per object in the Admin:

# books/admin.py
from django.contrib import admin
from rules.contrib.admin import ObjectPermissionsModelAdmin
from .models import Book

class BookAdmin(ObjectPermissionsModelAdmin):
    pass

admin.site.register(Book, BookAdmin)

Now this allows you to specify permissions like this:

rules.add_perm('books', rules.always_allow)
rules.add_perm('books.add_book', has_author_profile)
rules.add_perm('books.change_book', is_book_author_or_editor)
rules.add_perm('books.delete_book', is_book_author)

To preserve backwards compatibility, Django will ask for either view or change permission. For maximum flexibility, rules behaves subtly different: rules will ask for the change permission if and only if no rule exists for the view permission.


我已经使用了ObjectPermissionsModelAdmin,但是如上所述,传递的对象始终为None。(否则谓词根本不会被调用) - Tigerware
请将您的设置与django-rules存储库中的testapp进行比较 https://github.com/dfunckt/django-rules/blob/master/tests/testapp/rules.py 我正在检查使用谓词的测试,并且我可以看到正确传递了book。 - Kamil Niski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接