免责声明:我是django和django规则的新手。
我已经定义了我的模型。Model在用户表中有2个外键。创建者和主管。实例应由工作人员、创建者或主管进行更改/更新。
我为is_creator和is_supersvisor定义了谓词,并制定了一条规则:
@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
在模型元类中,我添加了:
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 %}
当我以超级用户身份登录时,按钮会按预期显示。当我使用一个应该能够编辑特定实例的测试用户时,按钮根本不会显示。因此,虽然进行了某些检查,但并不像预期的那样。
对于索引页面,我还有第二个类似的功能。仅显示用户有权限执行的操作。同样,超级用户看到了所有内容,但测试用户没有。
在这种情况下,我有下面的谓词,它被用作对不同模型的"添加"权限:
@rules.predicate
def can_add_xyz(user):
return rules.is_staff | rules.is_group_member("Add_XYZ")
在这两种情况下,除了is_staff之外的所有检查似乎都失败了。我做错了什么?
有两个问题。首先是RTF并正确执行:
在我的模板中,我使用了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框架序列化程序生成的相关实体。这意味着模板中使用的实例不是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
这解决了问题,现在显示了正确的内容,但我对此并不完全满意(类型检查(。因此,任何让情况变得更好的建议都是受欢迎的。