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
这解决了问题,现在显示了正确的内容,但我对此并不完全满意(类型检查)。因此,我们仍然欢迎任何改进的建议。
免责声明:我是 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
这解决了问题,现在显示了正确的内容,但我对此并不完全满意(类型检查)。因此,我们仍然欢迎任何改进的建议。