Django Rest Framework序列化器未获取CharField

时间:2019-12-05 12:53:17

标签: python django serialization django-rest-framework

我已经使用Django和Django Rest Framework构建了API。在我的序列化器中,我定义了一个organisation,可以发布,但需要存储到其他模型中。我将序列化器定义如下:

class DeviceSerializer(serializers.HyperlinkedModelSerializer):
    geometrie = PointField(required=False)
    organisation = serializers.CharField(source='owner.organisation')
    owner = PersonSerializer(required=False)

    class Meta:
        model = Device
        fields = (
            'id',
            'geometrie',
            'longitude',
            'latitude',
            'organisation',
            'owner',
        )

    def get_longitude(self, obj):
        if obj.geometrie:
            return obj.geometrie.x

    def get_latitude(self, obj):
        if obj.geometrie:
            return obj.geometrie.y

    def create(self, validated_data):
        print("ORG:", validated_data.get('organisation', "NO ORG FOUND")) # 
        # Do some custom logic with the organisation here

但是当我向其中发布包含organisation的json(我对输入进行了三遍检查)时,它将打印行ORG: NO ORG FOUND

为什么在地球上不转发组织?

[编辑]

型号代码:

class Person(models.Model):
    name = models.CharField(max_length=255)
    email = models.EmailField()
    organisation = models.CharField(max_length=250, null=True, blank=True)


class Device(models.Model):
    geometrie = gis_models.PointField(name='geometrie', null=True, blank=True)
    owner = models.ForeignKey(to='Person', on_delete=models.SET_NULL, null=True, blank=True, related_name='owner')

和测试代码:

def test_full_post(self):
    device_input = {
        "geometrie": {"longitude": 4.58565, "latitude": 52.0356},
        "organisation": "Administration."
    }
    url = reverse('device-list')
    self.client.force_login(self.authorized_user)
    response = self.client.post(url, data=device_input, format='json')
    self.client.logout()

4 个答案:

答案 0 :(得分:0)

尝试更改行:

print("ORG:", validated_data.get('organisation'], "NO ORG FOUND")) 

对此:

print("ORG:", validated_data.get('organisation', "NO ORG FOUND"))

答案 1 :(得分:0)

由于添加了 source 参数,DRF会自动将 organisation 数据推入 嵌套级别< / em>

因此,如果您想访问组织数据,请尝试以下操作,

class DeviceSerializer(serializers.HyperlinkedModelSerializer):
    organisation = serializers.CharField(source='owner.organisation')

    # other code stuffs
    def create(self, validated_data):
        organisation = validated_data['owner']['organisation']
        print("ORG:", organisation) 

答案 2 :(得分:0)

请尝试“ StringRelatedField”。

class DeviceSerializer(serializers.HyperlinkedModelSerializer):

    geometrie = PointField(required=False)
    organisation = serializers.CharField(source='owner.organisation')  # yours
    # ----------------
    organisation = serializers.StringRelatedField(source='owner.organisation')  # try this.
    owner = PersonSerializer(required=False)

    # your code

答案 3 :(得分:0)

由于您使用的是点号validated_data的序列化器字段,因此将是:

{
'geometrie': {'longitude': 4.58565, 'latitude': 52.0356}, 
'owner': {'organisation': 'Administration.'}
}

因此,您可以以validated_data['owner']['organisation']的身份访问组织

但是,如果您想序列化另一个相关表/外键的属性/列,则需要使用StringRelatedField [ organisation = serializers.StringRelatedField(source='owner.organisation')] 这样可以确保“设备instance fetched from the database contains the proper组织attribute during a获得`请求。

反序列化虽然无法正常工作,并且您需要在create方法中进行其他实现。这是因为您需要创建一个Person实例(带有organisation),然后将Device实例连接到该新创建的实例。

一个具体的例子可以在这里找到: Writing nested serializers