Django REST序列化器中丢失外键值

nhjlsmyf  于 2023-08-08  发布在  Go
关注(0)|答案(3)|浏览(137)

我已经简化了我的代码,使问题更清楚。
我在Django REST项目中有两个相关的模型。在我的models.py中:

class ClinicalResearch(models.Model):
    name = models.CharField(max_length=150, null=True)
    description = models.TextField(blank=True, null=True)

class Patient(models.Model):
    research = models.ForeignKey(ClinicalResearch, on_delete=models.CASCADE, blank=True)
    first_name = models.CharField(max_length=50)
    second_name = models.CharField(max_length=50, blank=True, null=True)
    middle_name = models.CharField(max_length=50, blank=True, null=True)
    location = models.CharField(max_length=50, blank=True)
    birth_date = models.DateTimeField(blank=True, null=True)
    observation_date = models.DateTimeField(blank=True, null=True)
    desease = models.CharField(max_length=50, blank=True, null=True)
    desease_date = models.DateTimeField(blank=True, null=True)
    gender = models.CharField(max_length=10)

字符串
然后我创建一个序列化器:

class PatientSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Patient
        fields = ('id', 'research_id', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
    def create(self, validated_data):
        # for tests only
        print(validated_data)
        return Patient(**validated_data)


视图集:

class PatientViewSet(viewsets.ModelViewSet):
    queryset = Patient.objects.all()
    serializer_class = PatientSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('id', 'research_id', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')


工艺路线:

router.register(r'patients', ItemViewSet)


这个实现对于没有外键的模型工作得很好。但是当我发布类似的内容时:

{
'id': null,
'research_id': 1,
'first_name': "john",
'second_name': "doe",
'middle_name', "",
'location': "Love Street",
'birth_date': "...",
'observation_date': "...",
'desease': "Lovefool",
'desease_date': "...",
"gender": "male to fem"
}


(the存在id=1的项目)
我的ItemSerializer没有传递{ research_id:1 }到validated_fields。
project_id字段在验证期间 * 完全丢失 *。
如何配置Serializer或ViewSet使其工作?

hjqgdpho

hjqgdpho1#

看起来像是与HyperlinkedModelSerializer相关的问题,在这种情况下,Django需要相关对象的url而不是id。尝试覆盖序列化器字段research的类型:

class PatientSerializer(serializers.HyperlinkedModelSerializer):
    research = serializers.PrimaryKeyRelatedField()
    class Meta:
        model = Patient
        fields = ('id', 'research', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
    def create(self, validated_data):
        # for tests only
        print(validated_data)
        return Patient(**validated_data)

    # If you need URLs for representation use this method
    def to_representation(self, instance):
        """Set field type for output only"""
        self.fields['research'] = serializers.HyperlinkedRelatedField()
        return super().to_representation(instance)

字符串

7xllpg7q

7xllpg7q2#

你必须链接它:
accept看起来像是与HyperlinkedModelSerializer相关的问题,在这种情况下Django需要相关对象的url而不是id。尝试覆盖序列化程序的字段研究类型:

class PatientSerializer(serializers.ModelSerializer):
    research = serializers.PrimaryKeyRelatedField(queryset=ClinicalResearch.objects.all())
    class Meta:
        model = Patient
        fields = ('id', 'research', 'first_name', 'second_name', 'middle_name', 'location', 'birth_date', 'observation_date', 'desease', 'desease_date', 'gender')
    def create(self, validated_data):
        # for tests only
        print(validated_data)
        return Patient.objects.create(**validated_data)

字符串

3npbholx

3npbholx3#

这个问题困扰了我很多次,但一直没有找到具体的解决办法。我分享我的解决方案,今天为我工作。希望它能保持正确的时间很长。
结果,我得到了以下我想要的结果:
1.我想为FK字段传递一个primary_key id。我的模型中有三个(3)。
1.我希望在我的GET响应中,所有字段值都是定义的。不只是FK的ID。因此使用深度=1。(这是第一个问题)
1.我不想为GET和POST API定义两个不同的序列化器。
这就是我的序列化器的样子:

class AppointmentSerializer(EnumSupportSerializerMixin, serializers.ModelSerializer):
    address = serializers.PrimaryKeyRelatedField(
        many=False, read_only=False, queryset=Address.objects.all()
    )

    slot = serializers.PrimaryKeyRelatedField(
        many=False, read_only=False, queryset=SlotAvailablity.objects.all()
    )
    service = serializers.PrimaryKeyRelatedField(
        many=False, read_only=False, queryset=Service.objects.all()
    )

    class Meta:
        model = Appointment
        fields = [
            "id",
            "title",
            "created_at",
            "patient",
            "address",
            "slot",
            "service",
            "status",
            "comment",
        ]
        extra_kwargs = {"status": {"required": False}}
        depth = 1

    def to_representation(self, instance):
        """Set field type for output only"""
        self.fields["address"] = AddressSerializer(read_only=True, many=False)
        self.fields["service"] = ServiceSerializer(read_only=True, many=False)
        self.fields["slot"] = SlotAvailabilitySerializer(read_only=True, many=False)
        return super().to_representation(instance)

字符串

相关问题