Search code examples
pythondjangoapiserializationtastypie

TastyPie Serializing during dehydrate


So I have a QuestionResource:

class QuestionResourse(ModelResource):
def dehydrate(self, bundle):
    bundle.data['responses'] = Responses.objects.filter(question_id=bundle.data['id'])
    return bundle
class Meta:
    resource_name='question'
    queryset = Questions.objects.all()
    allowed_methods = ['get', 'post']

If the url is something like https://domain.com/api/v1/question/, it should return the questions with the attribute responses attached. Although they are not being serialized.

{
"date": "2015-10-03T16:53:22",
"id": "1",
"question": "Where is my mind?",
"resource_uri": "/api/v1/question/1/",
"responses": "[<Responses: Responses object>, <Responses: Responses object>, <Responses: Responses object>, <Responses: Responses object>, <Responses: Responses object>]",
"totalresponses": 5
}

How do I serialize the <Responses: Responses object>? Also, how do I make "responses" into a json array and not a string?

EDIT: With the help of raphv, I used this code in my resources:

class ResponseResourse(ModelResource):
    class Meta:
        resource_name='response'
        queryset = Responses.objects.all()
        allowed_methods = ['get', 'post']
class QuestionResourse(ModelResource):
    responses = fields.ToManyField(ResponseResourse, attribute=lambda bundle: Responses.objects.filter(question_id = bundle.obj.id), full=True)
    class Meta:
        resource_name='question'
        queryset = Questions.objects.all()
        allowed_methods = ['get', 'post']

to produce:

{
"date": "2015-10-03T16:53:22",
"id": "1",
"question": "Where is my mind?",
"resource_uri": "/api/v1/question/1/",
"responses": [
    {
        "id": "54",
        "resource_uri": "/api/v1/response/54/",
        "response": "ooooooo oooooo",
    },
    {
        "id": "60",
        "resource_uri": "/api/v1/response/60/",
        "response": "uhh, test",
        "votes": 0
    }]
}

Solution

  • You should create a separate ResponseResource and link both in api.py.

    The full=True parameter is what makes the API return a full representation of each Response

    from tastypie import resources, fields
    
    class ResponseResource(resources.ModelResource):
        class Meta:
            resource_name = 'response'
            queryset = Responses.objects.all()
            ...
    
    class QuestionResource(resources.ModelResource):
        responses = fields.ToManyField(ResponseResource, 'responses', full=True)
        class Meta:
            resource_name='question'
            queryset = Questions.objects.all()
            ...