Django REST框架:通过多种关系进行序列化

时间:2016-07-27 21:27:30

标签: 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.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中的标准双下划线符号似乎不适用于此,因为我收到了错误:

  

字段名strain_species__species_genus对模型HostStrain无效。

我希望在我的HostStrain序列化中包含指向({至少__unicode__Genus模型的链接。

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

1 个答案:

答案 0 :(得分:2)

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

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