Django: Сериализаторы и запросы "один ко многим" и "многие к одному

У меня есть отношения, подобные этим: Один город имеет один ко многим зданиям; одно здание имеет ноль ко многим устройствам.

Пользователь должен иметь возможность запросить город по его PK, получив в ответ город, здания в городе и устройства в этих зданиях.

Я знаю, что внешние ключи необходимы при создании моделей, например, так:

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

У меня проблемы с тем, как написать сериализаторы и запросы. На данный момент мои сериализаторы включают только поля, соответствующие столбцам этой таблицы:

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', ...]

Однако, когда мне нужно ответить на GET-запрос о городе, я знаю только, как использовать вложенные циклы for для получения данных о здании и устройстве после нахождения города по введенному ID. Я предполагаю, что есть лучший способ, но мне трудно найти четкие ответы в Интернете.

Используйте ключевое слово related_name в ваших моделях, вы можете узнать больше об этом - вот как это работает -

  1. Определите свои модели и добавьте related_name к внешним ключам как -

    .
    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')
    
  2. Затем определите ваши сериализаторы в обратном порядке и добавьте related_name моделей в поле ваших сериализаторов--

    .
     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' ...]
    

Теперь, когда вы попытаетесь получить город, вы получите все здания, относящиеся к этому городу, а также все устройства, связанные с каждым зданием.

Существует еще один метод, называемый serializermethodfield, он очень полезен во многих областях, вы можете использовать любой из них в зависимости от вашего выбора.

Надеюсь, это поможет.

Вернуться на верх