【问题标题】:Django serializer, nested relation and get_or_createDjango 序列化器、嵌套关系和 get_or_create
【发布时间】:2019-03-18 16:33:33
【问题描述】:

我已经在这个问题上烦恼了一段时间了。我有两个模型:Acquisitions 和 RawDatas。

每个 RawData 有一个 Acquisition,但许多 RawData 可以有相同的 Acquisition。

我想在创建 RawDatas 时自动创建或获取 Acquisition 的实例。我希望能够使用序列化程序获取所有信息。

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

我的问题是,使用这个,如果我的 Acquisitions 实例已经存在,我会得到一个 non_field_errors 或另一个约束验证错误。

我想知道处理这个问题的正确方法是什么?

所以我可以使用嵌套序列化程序自动创建它,当我只想获得信息(例如 GET 请求)时,我可以拥有我需要的所有字段(两个模型的每个字段)。

提前感谢您的帮助!

【问题讨论】:

    标签: python django django-models django-serializer serialization


    【解决方案1】:

    试试这个:

    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
    

    【讨论】:

    • 很好,可以,谢谢,但是因为没有AcquisitionSerializer,当我尝试获取信息时,我只得到acq号,而不是像以前那样获取所有信息,我应该删除什么函数来获取这些信息?
    • 只需将其添加到您的RawDataSerializeracq = AcquisitionSerializer() 就在class Meta 之前。它应该可以解决问题。
    • 是的,它适用于获取请求,但我得到了这个:{'acq': {'non_field_errors': [ErrorDetail(string='字段植入,beg_acq,duration_acq 必须创建一个唯一集。' , code='unique')]}} 尝试使用现有采集添加新数据时。
    • 这与您的模型设计有关。您正在创建可能不需要的 unique_together 约束。
    • 是的,我需要这个约束来确保我不能有两个具有相同持续时间/植入/开始的收购。
    猜你喜欢
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 2017-07-12
    • 2020-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多