How to get authorized custom object in django-tastypie
I need to get an authorized custom object in a hydrate method, something like this:
class SalepointResource(ModelResource):
def hydrate(self, bundle):
user = bundle.request.user
But the request here is an empty HttpRequest object and does not have a custom method, although the user is authorized. Is there a way to get the user object?
source to share
As of TastyPie 0.9.15 I find this works:
def hydrate_user(self, bundle):
bundle.obj.user = bundle.request.user
return bundle
without the need for subclassing ModelResource
. Here user
are ForeignKey
models and resources. I am posting this as an answer because while it looks simple it took me a long time to figure it out.
source to share
Not sure if this is the best approach, but I ran into this problem by subclassing a class ModelResource
and overriding some of its methods. The ModelResource
object request
(which contains user
) is a parameter of the method obj_update
, but it is not passed to the method full_hydrate
, which in turn is called hydrate
. You have to make a few small changes to each of these methods to pass the object request
all the way down the chain.
Method changes are trivial. More details:
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, ValidationError
from tastypie.resources import ModelResource
from tastypie.exceptions import NotFound, BadRequest, InvalidFilterError, HydrationError, InvalidSortError, ImmediateHttpResponse
class MyModelResource(ModelResource):
def obj_create(self, bundle, request=None, **kwargs):
...
bundle = self.full_hydrate(bundle, request)
...
def obj_update(self, bundle, request=None, **kwargs):
...
bundle = self.full_hydrate(bundle, request)
...
def full_hydrate(self, bundle, request=None):
...
bundle = self.hydrate(bundle, request)
...
def hydrate(self, bundle, request=None):
...
return bundle
Then make your resource a subclass of this new class and override the new version hydrate
:
class MyModelResource(MyModelResource):
class Meta:
queryset = MyModel.objects.all()
def hydrate(self, bundle, request):
bundle.obj.updated_by_id = request.user.id
return bundle
I haven't tested this completely, but it seems to work so far. Hope it helps.
source to share