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

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

问题描述:

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

Since my model's custom save method takes request.user as an argument I'm unable to do POST/PUT requests.

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

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

I'm using SessionAuthentication() and have included the CSRF token.

这是相关的模型部分:

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

您可以覆盖 ModelResource 子类上的默认 save() 方法.查看默认实现显示 save() 是用一个包对象调用的,该对象同时包含请求和要保存的对象.

You could override the default save() method on your ModelResource subclass. Looking at the default implementation shows that save() is called with a bundle object which has both the request and the object to be saved.

不幸的是,在不复制大部分代码的情况下没有简单的方法来更改它,因为更改 Django 模型的 save() 签名相当不常见.您也许可以执行这样的操作,但我建议您仔细测试一下:

Unfortunately, there's no easy way to change this without copying most of that code because changing a Django model's save() signature is fairly uncommon. You might be able to do something like this, although I'd recommend testing it carefully:

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

参考文献: