2

假设我有:

模型.py

class Books(models.Model):
    owner = models.ForeignKey(User)
    title = models.CharField(max_length = 100)

api.py

class UserResource(ModelResource):
    #blhblahblah as usual

class BooksResource(ModelResource):

    owner= fields.ToOneField(UserResource, 'owner')

    class Meta:
        queryset = Books.objects.all()
        authorizarion = Authorization()

然后我发出:

curl --dump-header - -H "Content-Type: application/json" -X POST --data "{\"owner\" : \"/api/v1/user/1/\", \"title\" : \"foo\"}" http://localhost:8000/api/data/album/

它的工作,我得到了我的新Books

然后我尝试\"owner\" : \"/api/v1/user/1/\" 通过将其添加到BooksResource

def hydrate_owner(self, bundle):
    bundle.obj.owner = User.objects.get(pk = bundle.request.user.id)
    return bundle

当我在curl没有 的情况下再次这样做时\"owner\" : \"/api/v1/user/1/\",响应是404 not found

然后我尝试不同的方法:

def obj_create(self, bundle, request = None, **kwargs):
    return super(BooksResource, self).obj_create(bundle, request, owner = User.objects.get(pk = request.user.id))

或者

def obj_create(self, bundle, request = None, **kwargs):
    return super(BooksResource, self).obj_create(bundle, request, owner = User.objects.get(pk = bundle.request.user.id))

我仍然得到404 not found

伙计们能帮帮我吗?

4

2 回答 2

1

我开始沿着这条路径为新对象设置所有者,但是在对更新请求进行授权检查时遇到了麻烦(进行单元测试!)。

设置:对象 A - 由用户 X 拥有 来自用户 Y 的更新请求以修改对象 A(应该会失败)

对对象 A 的修改请求从用户 Y 进入 Tasty Pie,并且水合物覆盖将对象 A 的工作副本中的所有者设置为 Y。

接下来将请求发送到我的授权对象以检查用户 Y 是否可以修改该对象。我的授权代码查看对象并看到对象的所有者字段是 Y,所以我们可以开始了。哎呀!安全漏洞!

我决定做的是覆盖 ResourceModel 中的 obj_create() 并在那里进行分配。到目前为止,一切都很好!

例如

class SmApiNewsItem(ModelResource):
    owner = fields.ForeignKey(SmApiUser, 'owner')
    
    class Meta:
        if SMARF_AUTH_ON:
            authentication = ApiKeyAuthentication()
        authorization = ScsGdnAuthVisibleToAllEditOnlyByOwner()
        queryset = SmModelNewsItems.objects.all()
        resource_name = 'news_item'
        filtering = smMakeFilterAllFieldsFilter(SmModelNewsItems)
        ordering = smMakeOrderingFieldList(SmModelNewsItems)
        serializer = SmarfSerializer()

    def obj_create(self, bundle, **kwargs):
        bundle.data["owner"] = bundle.request.user
        return super(SmApiNewsItem, self).obj_create(bundle, **kwargs)
        

于 2015-03-05T20:22:49.513 回答
1

哦,显然这是我的愚蠢错误,

class BooksResource(ModelResource):

    owner= fields.ToOneField(UserResource, 'owner')

    class Meta:
        queryset = Books.objects.all()
        authorizarion = Authorization()

        def hydrate_owner(self, bundle):
            bundle.obj.owner = bundle.request.user.id
            return bundle

错误是缩进!hydrate_owner假设是BooksResource方法,所以我稍微更改了代码并且它可以工作:

class BooksResource(ModelResource):

    owner= fields.ToOneField(UserResource, 'owner')

    class Meta:
        queryset = Books.objects.all()
        authorizarion = Authorization()

    def hydrate_owner(self, bundle):
        bundle.data['owner'] = User.objects.get(pk = bundle.request.user.pk)
        return bundle
于 2012-11-19T07:20:13.397 回答