Как заставить create и retrieve работать в одном сериализаторе?
У меня несколько запутанная проблема, у меня есть следующие модели
class ModelA(models.Model):
name = models.CharField(max_length=64)
class ModelB(models.Model):
model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
и сериализаторы
class ModelASerializer(serializers.ModelSerializer):
class Meta:
model = ModelA
fields = '__all__'
class ModelBSerializer(serializers.ModelSerializer):
terminal = ModelASerializer(read_only=True)
class Meta:
model = ModelB
fields = '__all__'
когда я хочу создать объект ModelB, включающий модель_a_id, он имеет 2 ответа в зависимости от того, ставлю ли я read_only=True или False
Я хотел бы, чтобы при попытке создания через POST в объекте ModelB мне нужно было только отправить mode_a_id, но в то же время, когда я делаю GET, он возвращает сериализованные данные ModelASerializer в поле model_a.
Если я ставлю read_only = True, то работает только получение сериализованных данных в GET, но через POST я не могу присвоить идентификатор model_a
в случае read_only=False я не могу присвоить id этому объекту, так как он запрашивает словарь, я представляю, что нужно создать новый ModelA объект, но я хочу присвоить только тот, который уже существует.
Решением может быть размещение сериализатора с другим именем переменной, но мне бы очень хотелось, чтобы оно было одинаковым и для POST, и для GET.
Просто переопределите to_representation() метод вашего ModelBSerializer следующим образом.
class ModelASerializer(serializers.ModelSerializer):
class Meta:
model = ModelA
fields = '__all__'
class ModelBSerializer(serializers.ModelSerializer):
terminal = ModelASerializer(read_only=True)
class Meta:
model = ModelB
fields = '__all__'
def to_representation(self, instance):
pre_represented_data = super().to_representation(instance)
pre_represented_data['model_a'] = ModelASerializer(instance.model_a).data
return pre_represented_data
А если вы серьезно не хотите, чтобы id из ModelB в вызове GET, тогда просто удалите ключ из pre_represented_data, как показано ниже.
class ModelASerializer(serializers.ModelSerializer):
class Meta:
model = ModelA
fields = '__all__'
class ModelBSerializer(serializers.ModelSerializer):
terminal = ModelASerializer(read_only=True)
class Meta:
model = ModelB
fields = '__all__'
def to_representation(self, instance):
pre_represented_data = super().to_representation(instance)
pre_represented_data['model_a'] = ModelASerializer(instance.model_a).data
del pre_represented_data['id'] # deleting id of ModelB
return pre_represented_data