Search code examples
pythondjangotastypie

Tastypie get full resource only works the second time


I'm developing an Android application with backend developed using Tastypie and Django. I have a get request for which I want to optionally be able to retrieve the entire object (with complete related fields, rather than URIs). Below is part of the python code for the resource I'm talking about:

class RideResource(ModelResource):

    user = fields.ForeignKey(UserResource, 'driver')
    origin = fields.ForeignKey(NodeResource, 'origin', full=True)
    destination = fields.ForeignKey(NodeResource, 'destination', full=True)
    path = fields.ForeignKey(PathResource, 'path')

    # if the request has full_path=1 then we perform a deep query, returning the entire path object, not just the URI
    def dehydrate(self, bundle):
        if bundle.request.GET.get('full_path') == "1":
            self.path.full = True
        else:
            ride_path = bundle.obj.path
            try:
                bundle.data['path'] = _Helpers.serialise_path(ride_path)
            except ObjectDoesNotExist:
                bundle.data['path'] = []
        return bundle

As you can see the RideResource has a foreign key pointing to PathResource. I'm using the dehydrate function to be able to inspect if the GET request has a parameter "full_path" set to 1. In that case I set programmatically the path variable to full=True. Otherwise I simply return the path URI.

The thing is that the code seems to work only the second time the GET is performed. I've tested it hundreds of times and, when I perform my GET with full_path=1, even tho it enters the if and sets self.path.full = True, the first time it only returns the URI of the PathResource object. While, if I relaunch the exact same request a second time it works perfectly...

Any idea what's the problem?

EDIT AFTER SOLUTION FOUND THANKS TO @Tomasz Jakub Rup

I finally managed to get it working using the following code:

def full_dehydrate(self, bundle, for_list=False):
    self.path.full = bundle.request.GET.get('full_path') == "1"
    return super(RideResource, self).full_dehydrate(bundle, for_list)

def dehydrate(self, bundle):
    if not bundle.request.GET.get('full_path') == "1":
        try:
            bundle.data['path'] = _Helpers.serialise_path(bundle.obj.path)
        except ObjectDoesNotExist:
            bundle.data['path'] = []
    return bundle

Solution

  • dehydrate is called after full_dehydrate. Overwrite full_dehydrate function.

    def full_dehydrate(self, bundle, for_list=False):
        self.path.full = bundle.request.GET.get('full_path') == "1"
        return super(RideResource, self).full_dehydrate(bundle, for_list)