Django-tastypie将request.user传递给自定义保存方法

时间:2013-04-15 17:10:27

标签: python django tastypie

由于我的模型的自定义保存方法将request.user作为参数,我无法执行POST / PUT请求。

TypeError at /api/obsadmin/observation/23
save() takes at least 2 arguments (1 given)

我正在使用SessionAuthentication()并包含CSRF令牌。

以下是相关的模型部分:

def save(self, user, owner=None, *args, **kwargs):
    self.updated_by = user.id
    super(ObsModel, self).save(*args, **kwargs)

资源:

class ObservationResource2(ModelResource):

comments = fields.ToManyField(CommentResource2, 'comments', full=True, null=True)

class Meta:
    queryset = Observation.objects.filter(is_verified=True)
    authentication = SessionAuthentication()
    authorization = DjangoAuthorization()
    resource_name = 'observation'
    always_return_data = True

2 个答案:

答案 0 :(得分:5)

我刚刚通过使用内置的hydrate方法在保存之前修改数据,实现了同样的最终目标。 bundle.request方法内的hydrate中提供了当前请求。请参阅文档here

我通过Friend公开了FriendResource模型,我希望通过user ForeignKey字段链接到创建Django用户。

我的示例资源代码:

class FriendResource(ModelResource):
    class Meta:
        queryset = Friend.objects.all()
        resource_name = 'friend'
        excludes = ['slug',]
        authentication = SessionAuthentication()
        authorization = DjangoAuthorization()
        always_return_data = True

    def get_object_list(self, request):
        return super(FriendResource, self).get_object_list(request).filter(user=request.user)

    def hydrate(self, bundle):
        bundle.obj.user = bundle.request.user
        return bundle

希望有所帮助!

答案 1 :(得分:2)

您可以覆盖save()子类的默认ModelResource方法。查看default implementation显示使用包含请求和要保存的对象的包对象调用save()

不幸的是,没有简单的方法可以在不复制大部分代码的情况下更改它,因为更改Django模型的save()签名是相当罕见的。你可能会做这样的事情,虽然我建议你仔细测试一下:

from functools import partial

try:
    old_save = bundle.obj.save
    bundle.obj.save = partial(old_save, user=bundle.request.user)
    return super(FooResource, self).save(bundle)
finally:
    bundle.obj.save = old_save

参考文献: