2016-07-27 93 views
0

在Django中,我有以下模型。Django REST框架:通過多個關係序列化

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框架序列化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 .

我想包括一個鏈接到(或至少我的HostStrain序列化中的Genus模型的__unicode__

那麼,如何在Django REST框架的序列化中遵循多級關係?

回答

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'參數。謝謝! –

相關問題