Serialization Django REST框架:通过多个关系序列化

Serialization Django REST框架:通过多个关系序列化,serialization,django-rest-framework,Serialization,Django Rest Framework,在Django,我有以下模型 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.ForeignKe

在Django,我有以下模型

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中的标准双下划线符号在这里似乎不起作用,因为我得到了错误:

字段名<代码>菌株\种\种\属对模型<代码>宿主菌株无效

我想在我的主机中包括一个指向
Genus
模型的链接(或者至少是
\uuuuunicode\uuuuuuuuu


那么如何在Django REST框架的序列化中遵循多级关系呢?

有几种方法可以做到这一点

您可以在
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')

有几种方法可以做到这一点

您可以在
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')

第二种方法基本上就是我想要的,只是完全错过了文档中的
source
参数。谢谢第二种方法基本上就是我想要的,只是完全错过了文档中的
source
参数。谢谢