Как заставить 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