views:

289

answers:

2

I am using piston and I would like to spit out a custom format for my response.

My model is something like this:

class Car(db.Model):
   name = models.CharField(max_length=256)
   color = models.CharField(max_length=256)

Now when I issue a GET request to something like /api/cars/1/ I want to get a response like this:

{'name' : 'BMW', 'color' : 'Blue',
  'link' : {'self' : '/api/cars/1'}
}

However piston only outputs this:

{'name' : 'BMW', 'color' : 'Blue'}

In other words I want to customize the representation of a particular resource.

My piston Resource handler currently looks like this:

class CarHandler(AnonymousBaseHandler):
    allowed_methods = ('GET',)
    model = Car
    fields = ('name', 'color',)

    def read(self, request, car_id):
           return Car.get(pk=car_id)

So I don't really get where I have the chance to customize the data. Unless I have to overwrite the JSON emitter, but that seems like a stretch.

A: 

Django comes with a serialization library. You'll also need a json library to get it into the format you want

http://docs.djangoproject.com/en/dev/topics/serialization/

from django.core import serializers
import simplejson

class CarHandler(AnonymousBaseHandler):
    allowed_methods = ('GET',)
    model = Car
    fields = ('name', 'color',)

    def read(self, request, car_id):
           return simplejson.dumps( serializers.serialize("json", Car.get(pk=car_id) )
George
The question is about how to add fields to object JSON representation, not how to produce JSON.
Dmitry Risenberg
+4  A: 

You can return custom format by returning a Python dictionary. Here is an example on one of my app. I hope it helps.

from models import *
from piston.handler import BaseHandler
from django.http import Http404

class ZipCodeHandler(BaseHandler):
    methods_allowed = ('GET',)

    def read(self, request, zip_code):
        try:
            points = DeliveryPoint.objects.filter(zip_code=zip_code).order_by("name")
            dps = []
            for p in points:
                name = p.name if (len(p.name)<=16) else p.name[:16]+"..."
                dps.append({'name': name, 'zone': p.zone, 'price': p.price})
            return {'length':len(dps), 'dps':dps}    
        except Exception, e:
            return {'length':0, "error":e}
luc
So you CAN return a dictionary! Great stuff, didn't know that. Thanks!
drozzy
Wow, this is a pleasant surprise!
jathanism