2010-01-05 5 views
6

Sto usando il pistone e vorrei sputare un formato personalizzato per la mia risposta.Pistone personalizza la rappresentazione della risposta

Il mio modello è qualcosa di simile:

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

Ora, quando lancio una richiesta GET a qualcosa di simile/API/vetture/1/Voglio ottenere una risposta del genere:

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

Tuttavia pistone emette solo questo:

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

In altre parole voglio personalizzare la rappresentazione di un particolare risorsa.

mio gestore delle risorse pistone attualmente appare così:

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

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

quindi non ho davvero arrivare dove ho la possibilità di personalizzare i dati. A meno che non debba sovrascrivere l'emettitore JSON, ma sembra un allungamento.

risposta

6

È possibile tornare formato personalizzato restituendo un dizionario Python. Ecco un esempio su una delle mie app. Spero possa essere d'aiuto.

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} 
+0

Così puoi restituire un dizionario! Grandi cose, non lo sapevo. Grazie! – drozzy

+0

Wow, questa è una piacevole sorpresa! – jathanism

-2

Django viene fornito con una libreria di serializzazione. Avrete anche bisogno di una libreria JSON per farlo nel formato che si desidera

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)) 
+0

La domanda è su come aggiungere campi di opporsi rappresentazione JSON , non come produrre JSON. –

1

Sono passati due anni da quando è stata posta questa domanda, quindi è ovviamente in ritardo per OP. Ma per gli altri che, come me, hanno avuto un dilemma simile esiste un modo Pistonic per ottenere questo risultato.

Utilizzando l'esempio Django di sondaggi e scelte -

Si noterà che per il ChoiceHandler la risposta JSON è:

[ 
    { 
     "votes": 0, 
     "poll": { 
      "pub_date": "2011-04-23", 
      "question": "Do you like Icecream?", 
      "polling_ended": false 
     }, 
     "choice": "A lot!" 
    } 
] 

Questo include l'intera JSON per associato il sondaggio, mentre solo il id per avrebbe potuto essere altrettanto buono se non migliore.

Diciamo che il desiderato risposta è:

[ 
    { 
     "id": 2, 
     "votes": 0, 
     "poll": 5, 
     "choice": "A lot!" 
    } 
] 

Ecco come si potrebbe modificare il gestore per il raggiungimento di tale:

from piston.handler import BaseHandler 
from polls.models import Poll, Choice 

class ChoiceHandler(BaseHandler): 
    allowed_methods = ('GET',) 
    model = Choice 
    # edit the values in fields to change what is in the response JSON 
    fields = ('id', 'votes', 'poll', 'choice') # Add id to response fields 
    # if you do not add 'id' here, the desired response will not contain it 
    # even if you have defined the classmethod 'id' below 

    # customize the response JSON for the poll field to be the id 
    # instead of the complete JSON for the poll object 
    @classmethod 
    def poll(cls, model): 
    if model.poll: 
     return model.poll.id 
    else: 
     return None 

    # define what id is in the response 
    # this is just for descriptive purposes, 
    # Piston has built-in id support which is used when you add it to 'fields' 
    @classmethod 
    def id(cls, model): 
    return model.id 

    def read(self, request, id=None): 
    if id: 
     try: 
     return Choice.objects.get(id=id) 
     except Choice.DoesNotExist, e: 
     return {} 
    else: 
     return Choice.objects.all() 
+0

Esiste un equivalente per un campo nidificato? Sembra che il pistone supporti solo l'innesto, basato sul suo emitter.py – TankorSmash