简体   繁体   English

Django Rest Framework 序列化程序没有得到 CharField

[英]Django Rest Framework serializer doesn't get CharField

I've built an API using Django and Django Rest Framework.我已经使用 Django 和 Django Rest Framework 构建了一个 API。 In my serializer I defined an organisation which can be posted, but needs to be stored to a different model.在我的串行我定义的organisation可以发布,但需要被存储到不同的模式。 I defined my serializer as follows:我定义了我的序列化程序如下:

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

But when I post some json to it, which includes an organisation (I triple checked the input), it prints the line ORG: NO ORG FOUND .但是当我向它发布一些 json 时,其中包括一个organisation (我对输入进行了三次检查),它会打印一行ORG: NO ORG FOUND

Why on earth doesn't it forward the organisation?为什么它不转发组织?

[EDIT] [编辑]

The model code:型号代码:

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')

and the test code:和测试代码:

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()

Try changing the line:尝试更改行:

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

to this:对此:

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

Since you have added the source argument, DRF automatically push the organisation data into a nested level由于添加了source参数,DRF 会自动将organisation数据推送到嵌套级别

So, if you want to access the organisation data, try the following,因此,如果您想访问组织数据,请尝试以下操作,

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) 

Pls, try 'StringRelatedField'.请尝试“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

Since you are using a serializer field with dotted notation validated_data will be:由于您使用的是带点符号的序列化器字段, validated_data将是:

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

Hence, you can access organisation as validated_data['owner']['organisation']因此,您可以作为validated_data['owner']['organisation']访问组织

However, if you want to serialize a attribute/column of a another related table/foreign key you need to do use StringRelatedField [ organisation = serializers.StringRelatedField(source='owner.organisation') ] This would ensure that the 'Device instance fetched from the database contains the proper organisation attribute during a GET` request.但是,如果您想序列化另一个相关表/外键的属性/列,您需要使用StringRelatedField [ organisation = serializers.StringRelatedField(source='owner.organisation') ] 这将确保instance fetched from the database contains the proper “设备instance fetched from the database contains the proper attribute during a GET` 请求attribute during a instance fetched from the database contains the proper组织attribute during a

Deserialization won't work though and you would need additional implementation in the create method.但是反序列化不起作用,您需要在create方法中进行额外的实现。 This is because you need to create a Person instance (with the organisation ) and then connect the Device instance to that newly created instance.这是因为您需要创建一个Person实例(与organisation ),然后将Device实例连接到该新创建的实例。

A concrete example can be found here: Writing nested serializers一个具体的例子可以在这里找到: 编写嵌套序列化程序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM