首页 > 解决方案 > 嵌套写入序列化程序验证日期为空

问题描述

遵循最佳实践使用序列化程序创建嵌套对象,但是我仍然收到空的嵌套 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()}

标签: django-rest-framework

解决方案


对,这就是我看到的需要修复的地方:设计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 中定义如何向最终用户显示数据。如果您有任何问题,请告诉我。


推荐阅读