django-rules:无法使其在模板中按预期工作

django-rules: trouble making it work as expected in templates

免责声明:我是 django 和 django-rules 的新手。

我已经定义了我的模型。该模型有 2 个外键给用户 table。创作者和监督者。 实例应 changeable/updated 由工作人员、创建者或主管创建。

我已经为 is_creator 和 is_supervisor 定义了谓词并制定了规则:

@rules.predicate
def is_creator(user, mymodel):
    return mymodel.creator == user

@rules.predicate
def is_supervisor(user, mymodel):
    return mymodel.supervisor == user

can_edit = is_supervisor | is_creator | rules.is_staff

并且在模型元数据中 class 我添加了:

rules_permissions = {           
    'change': can_edit
}

在我看来,我想显示一个编辑按钮,该按钮链接到基于这些权限的编辑表单。

{% block content %}
{% has_perm 'mymodel.change_mymodel' user instance as can_edit %}
{% if can_edit %}
<button type="button" class="btn btn-warning"><h6>Edit</h6></button>
{% endif %}
{% endblock %}

当我以超级用户身份登录时,按钮按预期显示。 当我使用一个应该能够编辑特定实例的测试用户时,该按钮根本不显示。所以做了一些检查,但没有达到预期。

我对索引页有第二个类似的功能。仅显示用户有权执行的操作。同样,超级用户可以看到所有内容,但测试用户看不到。

在这种情况下,我有以下谓词,它在不同的模型上用作 "add" 权限:

@rules.predicate
def can_add_xyz(user):
    return rules.is_staff | rules.is_group_member("Add_XYZ")

似乎在这两种情况下,除了 is_staff 之外的所有检查似乎都失败了。我做错了什么?

有两个问题正在发生。首先 RTFM 并正确执行:

在我的模板中,我使用了 has_perm entity_name.add_entity_name 而不是按照文档 has_perm myapp.add_entity_name.

中的正确描述使用

在修复谓词现在实际被调用之后,我可以调试它们了。一个更大的问题暴露了出来。我能够修复它,但不喜欢修复。

谓词:

@rules.predicate
def is_creator(user, mymodel):
    return mymodel.creator == user

问题是在我检查此权限的模板中,mymodel 是由嵌套的 django-rest-framework 序列化程序生成的相关实体。这意味着模板中使用的然后提交给该谓词的实例不是 mymodel 实例而是 OrderedDict 因此我得到一个像 OrderedDict has no attribute 'creator'.

这样的异常

另一个问题是创建者不是直接的 Django auth_user 而是 OneToOne 扩展用户。所以 mymodel.creator == user 永远不会是真的。

@rules.predicate
def is_creator(user, mymodel):
    #if called from template as related entity,
    #mymodel is an OrderedDict from a serializer
    if isinstance(mymodel, collections.OrderedDict):        
        return mymodel["creator"] == user.userprofile.pk
    return mymodel.creator == user.userprofile

这解决了问题,现在显示了正确的内容,但我对此并不完全满意(类型检查)。因此,我们仍然欢迎任何改进的建议。