python - 为什么 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'
)
但是latitude
andlongitude
从来没有出现在print(validated_data)
. 有人知道他们为什么在那里失踪吗?
解决方案
编辑
下面的解决方案不像许多其他解决方案那样干净,例如这个答案中给出的解决方案如何使用 api 创建 PointField?. 我建议使用这个,但如果需要,我会在下面留给其他人
问题是您在数据中发送latitude
andlongitude
但模型只有一个称为几何的字段。我看到您正在尝试使用经过验证的数据进行设置,但经过验证的数据是针对模型字段检查的数据,因此您将无法在此处获取它。解决此问题的一种方法是在视图中添加上下文。
如果你的观点是这样的:
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)
推荐阅读
- android - 我无法在 android studio 模拟器中运行我的应用程序构建
- java - 设计问题:如何最好地使用构图
- android - 如何在 JUnit 5 扩展中存储值并在参数化测试中注入
- php - PHP 显示数据库中上传文件的人的用户名
- mysql - 高效执行复杂的 MySQL 查询
- c++ - D3D11 CreateSwapChainForHwnd 因 DXGI_ERROR_INVALID_CALL 或 E_INVALIDARG 而失败
- swift - 为什么 DispatchQueue.main.async 在 Swift 应用程序中不起作用?
- python - 如何找到下面的元素?. 我需要点击 Excel 图片
- java - 为什么我们需要在 Java 中重新定义寡妇关闭方法?
- android - 查看更改不正确