Сериализатор вложенных записей validated_date пуст - PullRequest
1 голос
/ 06 февраля 2020

Придерживался лучшего практического создания вложенных объектов с помощью сериализаторов, однако я все еще получаю пустые вложенные 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()}

1 Ответ

0 голосов
/ 07 февраля 2020

Правильно, вот что я вижу, что нужно исправить: обычный способ разработки 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% правильный. Возможно, это связано с тем, что вы используете один сериализатор для создания нового экземпляра, а другой - для отображения результата, когда в этом нет необходимости: вы можете указать, какие поля являются read_only, какие - write_only, а какие - нет. как для чтения, так и для записи, поскольку документация объясняет . Я предлагаю вам следовать схеме, которую я изложил выше, чтобы помочь вам, и определить в WriteOrganisationSiteSerializer, как показывать данные конечному пользователю. Дайте мне знать, если у вас возникнут проблемы.

...