在Django REST序列化程序中丢失外键值

时间:2018-05-29 15:12:37

标签: django django-rest-framework

我简化了我的代码,使问题更加清晰。

我的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"
}

(存在id = 1的项目)

我的ItemSerializer未将{research_id:1}传递给validated_fields。

在验证期间,project_id字段完全丢失

如何配置Serializer或ViewSet以使其可行?

2 个答案:

答案 0 :(得分:0)

在这种情况下看起来与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)

答案 1 :(得分:0)

你必须链接它:

接受 看起来像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)