Подтвердить что ты не робот

Как заставить Django-Piston включать связанные дочерние объекты в сериализованный вывод?

Я вытаскиваю свои волосы здесь, потому что это не работает для меня и кажется, что это должно быть.

Я использую Django-Piston для разработки API и имею 2 модели, Building and Building Area.

BuildingArea имеет ForeignKey для строительства, поскольку в здании есть несколько областей. Свойство "related_name" для FK - это "области", поэтому я могу получить доступ к BuildingAreas из данного здания.

Проблема в том, что все это прекрасно выглядит в Admin, но когда я попал в конечную точку /api/building.json, все, что я получаю, это объект Building без вложенных объектов BuildingArea, включенных в JSON.

Я бы подумал, что Django-Piston по умолчанию обратится к полям FK по умолчанию или мне что-то не хватает?

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 
4b9b3361

Ответ 1

Итак, я наконец-то начал работать после отладки через emitters.py и заметил, как он использует свойство "fields" обработчика для итерации полей Model.

Это мои модели:

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 

Вот как выглядит мой BuildingHandler:

class BuildingHandler(BaseHandler):

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

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

Важно отметить, что emmitters.py активирует некоторые кодировки только в том случае, если текущее определение поля представляет собой набор или список. Я забыл добавить трейлинг "," к наборам, используемым для определения полей, и это привело к тому, что Piston заставил Python возвращать набор, состоящий из символов, содержащихся в строке, "display_name", а не набор, содержащий строку ' отображаемое имя'. Надеюсь, что это имело смысл, Google "Python single set trailing comma" для получения дополнительной информации.

Надеюсь, это поможет кому-то еще!: D

Ответ 2

В BuildingHandler выполните:

fields = ('address', 'areas')

Это должно сделать это.