Django-tastypie pass request.user to custom save method

為{幸葍}努か 提交于 2019-12-12 10:26:16

问题


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)

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

Here's the relevant model part:

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

And the resource:

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

回答1:


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.

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

References:

  • obj_create: docs source
  • obj_update: docs source
  • save: source



回答2:


I've just achieved this same end goal by using the built-in hydrate methods to modify the data prior to saving. The current request is available in bundle.request inside the hydrate methods. See the docs here.

I have a Friend model exposed via FriendResource that I want to link to the creating Django user via a user ForeignKey field.

My example Resource code:

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

Hope that helps!



来源:https://stackoverflow.com/questions/16020890/django-tastypie-pass-request-user-to-custom-save-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!