django-rest-framework - 嵌套写入序列化程序验证日期为空
问题描述
遵循最佳实践使用序列化程序创建嵌套对象,但是我仍然收到空的嵌套 validate_data。
序列化器:
class WriteOrganisationSiteSerializer(serializers.ModelSerializer):
"""Organisation Site serializer class for post methods."""
site = WriteAPSiteSerializer()
class Meta:
model = models.OrganisationSite
fields = ("organisation", "site")
def create(self, validated_data):
from fadat.sites.models import APSite
site_data = validated_data.pop("site")
activeplaces_site_id = site_data.pop("activeplaces_site_id")
site, created = APSite.objects.get_or_create(
activeplaces_site_id=activeplaces_site_id, defaults=site_data
)
organisation_site = models.OrganisationSite.objects.create(
site=site, **validated_data
)
return organisation_site
class WriteAPSiteSerializer(serializers.Serializer):
"""Active Places Site serializer class for post methods."""
class Meta:
model = models.APSite
fields = (
"activeplaces_site_id",
"site_name",
"dependent_thoroughfare",
"thoroughfare_name",
"double_dependent_locality",
"dependent_locality",
"post_town",
"postcode",
"easting",
"northing",
"longitude",
"latitude",
)
风景
class OrganisationSitesView(APIView):
"""Organisation Sites API view."""
def post(self, request, **kwargs):
user = request.user
ser = serializers.WriteOrganisationSiteSerializer(data=request.data)
ser.is_valid(raise_exception=True)
obj = ser.save()
ser = serializers.ReadOrganisationSiteSerializer(obj)
return Response(ser.data, status=201)
运行以下测试(或通过浏览器 ajax 请求,相同的结果)
def test_add_organisation_site(self):
user = User.objects.create(email="newbie@dat.example.com")
organisation_type = OrganisationType.objects.create(name="Club")
organisation = Organisation.active_objects.create(
name="Club", organisation_type=organisation_type
)
site = {
"activeplaces_site_id": 1200341,
"site_name": "CITY OF LONDON SCHOOL",
"dependent_thoroughfare": "",
"thoroughfare_name": "QUEEN VICTORIA STREET",
"double_dependent_locality": "",
"dependent_locality": "",
"post_town": "LONDON",
"postcode": "EC4V 3AL",
"easting": 531990,
"northing": 180834,
"longitude": -0.099387,
"latitude": 51.511025,
}
body = {
"organisation": organisation.id,
"site": site,
}
self.authenticate(user)
url = reverse("api:inspections:organisation-sites")
res = self.client.post(url, json.dumps(body), content_type="application/json; charset=utf-8")
self.assertEqual(res.status_code, 201)
在我的视图中收到以下标题
{'organisation': 1, 'site': {'activeplaces_site_id': 1200341, 'site_name': 'CITY OF LONDON SCHOOL', 'dependent_thoroughfare': '', 'thoroughfare_name': 'QUEEN VICTORIA STREET', 'double_dependent_locality': '', 'dependent_locality': '', 'post_town': 'LONDON', 'postcode': 'EC4V 3AL', 'easting': 531990, 'northing': 180834, 'longitude': -0.099387, 'latitude': 51.511025}}
在视图中request.data
显示我
{'Cookie': '', 'Content-Length': '368', 'Content-Type': 'application/json; charset=utf-8', 'Authorization': 'Token 0081d8a36d90f1d922a2a7df494afe127a220495'}
仍然序列化不验证嵌套字段并返回
{'organisation': <Organisation: Club (Club)>, 'site': OrderedDict()}
解决方案
对,这就是我看到的需要修复的地方:设计post()
方法的常规方法如下:
def post(self, request, **kwargs):
serializer = serializers.WriteOrganisationSiteSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
尽管您的情况在许多方面是等效的,但显然不是 100% 正确。也许这与您使用一个序列化程序来创建新实例和另一个显示结果的事实有关,当不需要时:您可以设置哪些字段是只读的,哪些是只写的,以及那些正如文档所解释的那样,既可以读取又可以写入。我建议您按照我上面列出的模式来指导您,并在 WriteOrganisationSiteSerializer 中定义如何向最终用户显示数据。如果您有任何问题,请告诉我。
推荐阅读
- mysql - MySQL中的递归CTE丢失日期
- node.js - $geoNear 仅在我给出 maxDistance = 100 * 1000 时给出结果;
- chronicle-map - 在 Chronicle Map 中存储的值中查看垃圾值
- bootstrap-modal - 关闭并重新显示后引导模式不显示 PDF 文档
- reactjs - 有没有更好的方法来定义反应组件列表的类型?
- javascript - 如何将 ArrayBuffer 的特定范围设置为随机数?
- ruby-on-rails - 没有 storage.buckets.list 访问 Google Cloud 项目的权限?
- android - 无法在文本视图上显示翻译的文本
- mongodb - HTTP .get() 方法不响应任何内容
- css - 如何将所有 Kibana 徽标更改为其他徽标?