2010-02-21 20 views
12

Estoy tirando de mi cabello aquí porque esto no funciona para mí y parece que debería ser.¿Cómo hago que Django-Piston incluya objetos secundarios relacionados en la salida serializada?

Estoy usando Django-Piston para desarrollar una API y tengo 2 modelos, Construcción y Construcción.

BuildingArea tiene una ForeignKey to Building ya que hay varias áreas en un edificio. La propiedad 'related_name' para el FK es 'áreas' para que pueda acceder a BuildingAreas desde un edificio determinado.

El problema es que todo se ve bien en Admin pero cuando toco el /api/building.json endpoint, todo lo obtengo del objeto Building sin los objetos BuildingArea anidados incluidos en el JSON.

Hubiera pensado que Django-Piston seguiría campos FK inversos por defecto o me falta algo?

handlers.py

class BuildingHandler(BaseHandler): 

    allowed_methods = ('GET',)  
    model = Building 

    def read(self, name=None): 
     return self.model.objects.all() 

models.py

class Building(models.Model): 
    address   = models.CharField(max_length=255) 

    def __unicode__(self): 
     return self.address 

class BuildingArea(models.Model): 
    display_name = models.CharField(max_length=30) 
    building  = models.ForeignKey(Building, related_name='areas') 

    def __unicode__(self): 
     return self.display_name 

Respuesta

19

Ok, así que funcionó finalmente después de la depuración a través de emitters.py y observando cómo usa la propiedad 'campos' del manejador para iterar los campos del Modelo.

Estos son mis modelos:

class Building(models.Model): 
    address   = models.CharField(max_length=255) 

    def __unicode__(self): 
     return self.address 

class BuildingArea(models.Model): 
    display_name = models.CharField(max_length=30) 
    building  = models.ForeignKey(Building, related_name='areas') 

    def __unicode__(self): 
     return self.display_name 

Esto es lo que mi BuildingHandler ve ahora:

class BuildingHandler(BaseHandler): 

    allowed_methods = ('GET',)  
    fields = ('address', ('areas', ('display_name',),),)  
    model = Building 

    def read(self, name=None): 
     return self.model.objects.all() 

Lo importante a destacar aquí es que emmitters.py activará cierta rutas de código solo si la definición de campo actual es un conjunto o una lista. Me olvidé de agregar un ',' final a los conjuntos utilizados para definir los campos y esto hizo que Piston hiciera que Python devolviera un conjunto formado por los caracteres contenidos en la cadena, 'nombre_visualización', en lugar de un conjunto que contiene la cadena ' nombre para mostrar'. Espero que tenga sentido Google 'Python single set final coma' para más información.

¡Espero que esto ayude a otra persona! : D

+0

DIEZ MIL votos a favor señor (o señora). O al menos uno. De alguna manera, debería perderme eso. Piston continúa sorprendiéndome. – winsmith

+0

Tan loco como pensé que era esta respuesta, esta es la correcta. +1 y marcado para cuando lo olvide. –

+0

Ahora que me ha ahorrado mucho tiempo. – julkiewicz

0

En BuildingHandler, hacer:

fields = ('address', 'areas') 

Eso debería hacerlo.

+0

Ok Debo haber metido algo porque pensé que ya lo había intentado. Lo intentaré e informaré. – Ashemah

+0

Ok, lo intenté y todavía no funciona - salida es: [{"areas": "", "address": "42 Frigate Crescent"}] Pero definitivamente hay un BuildingArea en el db con su relación establecida correctamente para señalar a Edificio. – Ashemah

Cuestiones relacionadas