Reputation: 970
In Django, I have the following models.
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)
...
Now I'm trying to use Django REST Framework to serialize the the HostStrain model as follows.
class HostStrainSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = HostStrain
fields = ('strain_species__species_genus','strain_species','strain_name')
But the standard double-underscore notation in Django doesn't seem to work here, since I get the error:
Field name
strain_species__species_genus
is not valid for modelHostStrain
.
I'd like to include a link to (or at least the __unicode__
from) the Genus
model in my HostStrain serialization.
So how do I follow multi-level relationships in Django REST Framework's serialization?
Upvotes: 1
Views: 904
Reputation: 196
There are a few ways you can do this.
You can include other serializers on your 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')
This way your serializer will output something like this:
{
"strain_name": "...",
"strain_species": {
"species_genus": {
"genus_name": "..."
}
}
}
Another way you can do this is to create fields on your HostStrainSerializer
that gets the information from the other models.
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')
You can also use a 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')
Upvotes: 2