问题
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