2016-07-27 3 views
0

В Django у меня есть следующие модели.Django REST Framework: сериализация через множественные отношения

class Genus(models.Model): 
    genus_name=models.CharField(max_length=30) 
    ... 

class HostSpecies(models.Model): 
    species_genus=models.ForeignKey(Genus) 
    ... 

class HostStrain(models.Model): 
    strain_species=models.ForeignKey(HostSpecies) 
    strain_name=models.CharField(max_length=50) 
    ... 

Теперь я пытаюсь использовать Django REST Framework для сериализации модели HostStrain следующим образом.

class HostStrainSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = HostStrain 
     fields = ('strain_species__species_genus','strain_species','strain_name') 

Но стандарт двойного подчеркивания обозначения в Django, кажется, не работает здесь, так как я получаю ошибку:

Field name strain_species__species_genus is not valid for model HostStrain .

я хотел бы включить ссылку на (или, по крайней мере, __unicode__ от) модели Genus в моей сериализации HostStrain.

Как я могу следить за многоуровневыми отношениями в сериализации Django REST Framework?

ответ

1

Есть несколько способов сделать это.

Вы можете включать другие сериализаторы на вашем HostStrainSerializer

class GenusSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Genus 
     fields = ('genus_name') 

class HostSpeciesSerializer(serializers.HyperlinkedModelSerializer): 
    species_genus = GenusSerializer() 

    class Meta: 
     model = HostSpecies 
     fields = ('species_genus') 

class HostStrainSerializer(serializers.HyperlinkedModelSerializer): 
    strain_species = HostSpeciesSerializer() 

    class Meta: 
     model = HostStrain 
     fields = ('strain_species','strain_name') 

Таким образом, ваш сериалайзер будет выводить что-то вроде этого:

{ 
    "strain_name": "...", 
    "strain_species": { 
     "species_genus": { 
      "genus_name": "..." 
     } 
    } 
} 

Другим способом вы можете сделать это, чтобы создать поля на ваш HostStrainSerializer, который получает информацию с других моделей.

class HostStrainSerializer(serializers.HyperlinkedModelSerializer): 
    strain_species = HostSpeciesSerializer() 
    species_genus = serializers.ReadOnlyField(source='strain_species.species_genus.genus_name') 

    class Meta: 
     model = HostStrain 
     fields = ('species_genus', 'strain_species','strain_name') 

Вы также можете использовать SerializerMethodField

class HostStrainSerializer(serializers.HyperlinkedModelSerializer): 
    strain_species = HostSpeciesSerializer() 
    species_genus = serializers.SerializerMethodField() 

    def get_species_genus(self, instance): 
     return instance.strain_species.species_genus.genus_name 

    class Meta: 
     model = HostStrain 
     fields = ('species_genus', 'strain_species','strain_name') 
+0

Второй метод заключается в основном то, что я был после, и только полностью пропустил 'source' параметр в документации. Благодаря! –

Смежные вопросы