I have a relationship similar to this: One city has one-to-many buildings; one building has zero-to-many devices.
The user must be able to request a city by its PK, receiving in response the city, the buildings in the city, and the devices in those buildings.
I know that foreign keys are necessary in creating the models, like this:
class City(models.Model):
#Columns here
class Building(models.Model):
cityId = models.ForeignKey(City, on_delete=models.CASCADE)
#Columns here
class Device(models.Model):
buildingId = models.ForeignKey(Building, on_delete=models.CASCADE)
#Columns here
What I'm having trouble with is how to write the serializers and the queries. As of now, my serializers only include fields corresponding to that table's columns:
class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City
fields = ['id', ...]
class BuildingSerializer(serializers.ModelSerializer):
class Meta:
model = Building
fields = ['id', 'cityId', ...]
class DeviceSerializer(serializers.ModelSerializer):
class Meta:
model = Device
fields = ['id', 'buildingId', ...]
However, when I have to respond to a GET request for the city, I only know how to use a nested for loops to get the building and device data after finding the city by the inputted ID. I presume there's a better way, but I'm having trouble finding clear answers online.
CodePudding user response:
Use related_name keyword in your models, you can learn more about it -- here is how it works--
Define you models and add related_name to the foreign keys as -
class City(models.Model): ##fields class Building(models.Model): cityId = models.ForeignKey(City, on_delete=models.CASCADE,related_name='abc') class Device(models.Model): buildingId = models.ForeignKey(Building, on_delete=models.CASCADE, related_name='xyz')
Then define your serializers in reverse order and add the related_name of models in your serializers field--
class DeviceSerializer(serializers.ModelSerializer): class Meta: model = Device fields = ['id', 'buildingId', ...] class BuildingSerializer(serializers.ModelSerializer): xyz = DeviceSerializer(many=True, read_only=True) class Meta: model = Building fields = ['id', 'cityId', xyz ...] class CitySerializer(serializers.ModelSerializer): abc = BuildingSerializer(many=True, read_only=True) class Meta: model = City fields = ['id', 'abc' ...]
Now when you will try to get the city, you will get all the building rel;ated to that city and also all the Devices related to each building.
There is one another method called as serializermethodfield, this is of great use in many areas, you can use any one depending upon your choice.
Hope this helps..