Сериализатор Django, вложенные отношения и get_or_create - PullRequest
0 голосов
/ 18 марта 2019

Я уже давно сталкиваюсь с этой проблемой.У меня есть две модели: Приобретения и RawDatas.

У каждого RawData есть одно Приобретение, но у многих RawDatas может быть одно и то же Приобретение.

Я хочу автоматически создать или получить экземпляр Приобретения при созданиимои RawDatas.И я хочу иметь возможность получать всю информацию, используя сериализатор.

class Acquisitions(models.Model):
    class Meta:
        unique_together = (('implant', 'beg_acq', 'duration_acq'),)

    id = models.AutoField(primary_key=True)
    implant = models.ForeignKey("Patients", on_delete=models.CASCADE)
    beg_acq = models.DateTimeField("Beggining date of the acquisition")
    duration_acq = models.DurationField("Duration of the acquisition")

class RawDatas(models.Model):
    class Meta:
    unique_together = (('acq', 'data_type'),)

    id = models.AutoField(primary_key=True)
    acq = models.ForeignKey("Acquisitions", on_delete=models.CASCADE)
    data_type = models.CharField(max_length=3)
    sampling_freq = models.PositiveIntegerField("Sampling frequency")
    bin_file = models.FileField(db_index=True, upload_to='media')

И мои сериализаторы таковы:

class AcquisitionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Acquisitions
        fields = ('id', 'implant', 'beg_acq', 'duration_acq')

class RawDatasSerializer(serializers.ModelSerializer):
    acq = AcquisitionSerializer()

    class Meta:
        model = RawDatas
        fields = ('id', 'data_type', 'sampling_freq', 'bin_file', 'acq')

    def create(self, validated_data):
        acq_data = validated_data.pop('acq')
        acq = Acquisitions.objects.get_or_create(**acq_data)
        RawDatas.objects.create(acq=acq[0], **validated_data)
        return rawdatas

Моя проблема заключается в том, что при использовании этого, если мой экземплярПриобретение уже существует, я получаю non_field_errors или другую ошибку проверки ограничения.

Я хотел бы знать, как правильно это исправить, пожалуйста?

Таким образом, я могу автоматически создать это, используя вложенный сериализатор, и когда мне нужно только получить информацию (например, запрос GET), я могу получить все необходимое поле (каждое поле двух моделей).

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 18 марта 2019

Попробуйте это:

class AcquisitionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Acquisitions
        fields = ('id', 'implant', 'beg_acq', 'duration_acq')

class RawDatasSerializer(serializers.ModelSerializer):
    class Meta:
        model = RawDatas
        fields = ('id', 'data_type', 'sampling_freq', 'bin_file', 'acq')

    def create(self, validated_data):
        acq_data = validated_data.pop('acq')
        acq = Acquisitions.objects.filter(id=acq_data.get('id')).first()

        if not acq:
            acq = AcquisitionSerializer.create(AcquisitionSerializer(), **acq_data)

        rawdata = RawDatas.objects.create(acq=acq, **validated_data)

        return rawdata
...