Search code examples
pythondjangotastypie

Django-tastypie pass request.user to custom save method


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

Solution

  • 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: