【问题标题】:Tastypie Authorization not exactly authorizating?Tastypie 授权不完全授权?
【发布时间】:2016-02-14 12:18:43
【问题描述】:

假设我们希望能够仅更新阶段整数字段小于 3 的那些对象。(或类似的示例,我们希望将对象更新的权限限制为所有者 users=fields .外键)。所以第一个示例授权将如下所示:

class RecordAuthorization(Authorization):
    def update_detail(self, object_list, bundle):
        if bundle.obj.stage < 3:
            return True
        raise Unauthorized("You can't update this")

或第二个例子:

class RecordAuthorization(Authorization):
    def update_detail(self, object_list, bundle):
        if bundle.obj.user == bundle.request.user:
            return True
        raise Unauthorized("You can't update this")

实际上它们都不起作用(我测试了第一个但它不起作用)。 当您仔细查看 sweetpie 文档时,他们会说:

object_list 是正在处理的对象的集合,作为 请求。

所以这意味着在object_list 中,有json 对象只重写为python 字典列表?所以没有来自数据库的真实对象,因此这个过滤:

def update_list(self, object_list, bundle):
    return object_list.filter(stage__lt=3)

不会按预期工作(只允许更新阶段低于 3 的对象)。并且会做类似-> 如果 json(通过 API 发送,而不是数据库中的对象)阶段低于 3 允许更新。因此,实际上您可以将 stage=5(在数据库中)的对象更新为 stage=1! 对于 update_detail 函数,我也得到了同样奇怪的结果。所以我怀疑 bundle.obj 也是对象,但已经具有“json-updated”属性。

所以为了让事情顺利进行,我需要这样做:?!

class RecordAuthorization(Authorization):
    def update_detail(self, object_list, bundle):
        if User.objects.get(pk=bundle.obj.user.pk) == bundle.request.user:
            return True
        raise Unauthorized("You can't update this")

【问题讨论】:

    标签: python django tastypie


    【解决方案1】:

    对于update_listobject_list 参数将是一个应该被过滤的查询集(或其他可迭代的非 Django ORM 数据源)。

    对于update_detail,您要检查bundle.obj 的属性,这是您的Resource.Meta.object_class 的一个实例,例如Django 模型。如果您设置了Resource.Meta.queryset,则为您设置了Resource.Meta.object_class

    您的代码中存在缩进错误,您应该在方法级别而不是类级别引发 Unauthorized。如果修复不能解决问题,请发布您的资源。

    【讨论】:

    • 我现在修复了缩进。我知道 object_list 将是一个查询集,而 bundle.obj 将是 Model 实例(对我来说 - Django ORM)。问题是 update_list/detail 中的 object_list 和 bundle.obj 都包含来自数据库和来自当前请求的数据 => API 调用中指定的字段将覆盖数据库中的字段。对我来说(我也认为对某些人来说)这是一个意想不到的行为。我个人认为这些方法中会有两个数据:来自数据库的数据和来自 api 调用的数据(缺少字段数据库补充)
    • 但我只得到后一种数据。当然,我可以自己查询数据库,但是当 sweetpie 也查询数据库时,我认为它也会保留数据库中的原始模型。特别是对于 update_list 函数,编写查询似乎很重要,因为我需要从查询集中提取 ID 并使用这些 ID 运行另一个查询。(如果查询集上有一个简单的函数可以重新运行它,请告诉我)
    • 我明白你在说什么。现在我只想做另一个查询。在下一个版本中,我会将原始对象添加到包中。这是问题所在:github.com/django-tastypie/django-tastypie/issues/1448
    猜你喜欢
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-13
    • 2013-07-18
    • 2012-02-01
    • 2018-11-21
    相关资源
    最近更新 更多