首页 > 解决方案 > 为什么 Django Rest 框架不显示发布的纬度?

问题描述

我有一个 Django 代码库,它使用Django Rest Framework (DRF)作为 API,将数据库的内容提供给前端。

我现在还希望用户能够通过此 API 发布新内容。我得到了接受 POST 的 API,但是我遇到了gis Pointfield的问题。

在我的一个模型中,我有以下字段:

from django.contrib.gis.db import models as gis_models

class Device(models.Model):
    geometry = gis_models.PointField(name='geometry', null=True, blank=True)
    # And some other fields

latitude我让人们在两个单独的字段 (和) 中发布几何图形,longitude然后我想将它们写入该geometry字段。我有一个看起来像这样的 DeviceSerializer:

类 DeviceSerializer(HALSerializer): 类型 = TypeSerializer(many=True) 经度 = serializers.SerializerMethodField() 纬度 = serializers.SerializerMethodField() 组织 = serializers.SerializerMethodField()

class Meta:
    model = Device
    fields = (
        '_links',
        'id',
        'types',
        'longitude',
        'latitude',
        'organisation'
    )

def get_organisation(self, obj):
    if obj.owner:
        return obj.owner.organisation
    return 'Unknown'

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

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

def create(self, validated_data):
    print(validated_data)  # IN HERE I DON'T RECEIVE THE POSTED LATITUDE AND LONGITUDE

    types_data = validated_data.pop('types')
    device = Device.objects.create(**validated_data)
    for type_data in types_data:
        Type.objects.create(device=device, **type_data)

    if 'longitude' in validated_data and 'latitude' in validated_data:
        # WE NEVER REACH THIS POINT BECAUSE THE LAT AND LONG ARE NEVER POSTED
        device.geometry = Point(validated_data.pop('longitude'), validated_data.pop('latitude'))

    return device

在我的测试中,我然后这样做:

response = self.client.post(
    url,
    data={'types': [], 'latitude': 1, 'longitude': 1, 'organisation': 'abc'},
    format='json'
)

但是latitudeandlongitude从来没有出现在print(validated_data). 有人知道他们为什么在那里失踪吗?

标签: pythondjangoserializationdjango-rest-framework

解决方案


编辑

下面的解决方案不像许多其他解决方案那样干净,例如这个答案中给出的解决方案如何使用 api 创建 PointField?. 我建议使用这个,但如果需要,我会在下面留给其他人


问题是您在数据中发送latitudeandlongitude但模型只有一个称为几何的字段。我看到您正在尝试使用经过验证的数据进行设置,但经过验证的数据是针对模型字段检查的数据,因此您将无法在此处获取它。解决此问题的一种方法是在视图中添加上下文。

如果你的观点是这样的:

class MyView():
    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data,
            context={
                "latitude": request.data.get('latitude')
                "longitude": request.data.get('longitude')
            },
        )
        if serializer.is_valid:
            serilazer.save()

然后在序列化程序中,您可以validate使用

def validate(self, attrs):
    latitude = self.context.get("latitude")
    longitude = self.context.get("longitude")
    attrs.update(
        {
            "geometry": Point(latitude, longitude)
        }
    )
    return super().validate(attrs)

推荐阅读