2017-01-15 4 views
0

Я не могу понять, как сериализовать запрос, который включает в себя поля из обратной модели. Мои модели выглядят так. Каждый голос связан с одного альбома:Django - получить сериализованные поля из родственной модели

# models.py 

class Album(models.Model): 
    name = models.CharField(max_length=50) 

class Vote(models.Model): 
    album = models.ForeignKey(Album, on_delete=models.CASCADE) 
    user_vote = models.BooleanField(default=0) 

То, что я хотел бы сделать, это выполнить запрос, который возвращает все объекты альбома, а также сумму голосов, приписанных к этому альбому. Это достаточно легко, но когда я сериализация запроса, поле «total_votes» потерянно:

# views.py 

# this works fine 
query = Album.objects.annotate(total_votes = Sum(vote__user_vote)) 

# after serialization, I lose the field "total_votes" 
serialized = serializers.serialize('json', list(query)) 
return serialized 

К сожалению, поле «total_votes» не появляется в сериализованном результате, так как, согласно Джанго документации, «только поля, локально определенные на модели, будут сериализованы ».

Итак, мой вопрос в том, как получить следующий последовательный результат (при условии, что 100 голосов для Abbey Road и 150 для Astral Weeks)? Любая помощь будет принята с благодарностью.

[ 
{ 
    "pk": 1, 
    "model": "app.album", 
    "fields": { 
    "name": "Abbey Road", 
    "total_votes": 100 
}, 
{ 
    "pk": 2, 
    "model": "app.album", 
    "fields": { 
    "name": "Astral Weeks", 
    "total_votes": 150 
}, 
... 
] 

ответ

1

По словам источника, нет никакого способа сделать это с помощью serializers.serialize. База Джанго сериализатор будет только сериализации local_fields на экземпляре модели:

 for field in concrete_model._meta.local_fields: 
      if field.serialize: 
       if field.remote_field is None: 
        if self.selected_fields is None or field.attname in self.selected_fields: 
         self.handle_field(obj, field) 
       else: 
        if self.selected_fields is None or field.attname[:-3] in self.selected_fields: 
         self.handle_fk_field(obj, field) 
     for field in concrete_model._meta.many_to_many: 
      if field.serialize: 
       if self.selected_fields is None or field.attname in self.selected_fields: 
        self.handle_m2m_field(obj, field) 

Для того, чтобы получить то, что вы хотите, вы должны свернуть свою собственную функцию сериализации (например, то, что превращает модель в Словарь и затем использует DjangoJSONEncoder).