Django Tastypie使用当前用户资源填充字段



假设我有:

models.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

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

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

当我在没有"owner" : "/api/v1/user/1/"的情况下再次curl时,响应是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

伙计们能帮我吗?

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

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

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

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

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

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

我决定做的是覆盖资源模型中的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)
        

最新更新