PATCH (частичное = true) не работает в Django - PullRequest
1 голос
/ 23 марта 2020

У меня есть конечная точка PATCH, чтобы изменить некоторые необязательные данные для «сайта». Через конечную точку вы сможете редактировать описание и поставщика с сайта. Описание уже работает над существующим проектом. Когда я пытаюсь добавить поставщика в PATCH, он не обновляет его ..

Просмотр:

class AdminSiteDetailView(GenericAPIView):
    def get_permissions(self):
        return IsAuthenticated(),

    def get_serializer_class(self):
        return AdminSiteDetailSerializer

    @swagger_auto_schema(
        responses={
            200: openapi.Response(
                _("Successfully"),
                AdminSiteDetailSerializer,
            )
        }
    )
    def get(self, request, site_pk):
        """
        GET the data from the site.
        """
        #somecode

    @swagger_auto_schema(
        responses={
            200: openapi.Response(
                _("Successfully"),
                AdminSiteDetailSerializer,
            )
        }
    )
    def patch(self, request, site_pk):
        """
        PATCH the description of the site.
        """

        site = get_object_or_404(Site, pk=site_pk)
        serializer_class = self.get_serializer_class()
        serializer = serializer_class(site, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        site.save()
        return Response(serializer.data, status=status.HTTP_200_OK)

Сериализатор:

class AdminSiteSerializer(serializers.ModelSerializer):
    supplier = serializers.SerializerMethodField()

    class Meta:
        model = Site
        fields = [
            "id",
            "name",
            "supplier",
        ]

    @staticmethod
    def get_supplier(site):
        if not site.supplier:
            return None
        return SupplierSerializer(site.supplier).data


class AdminSiteDetailSerializer(AdminSiteSerializer):
    class Meta(AdminSiteSerializer.Meta):
        fields = AdminSiteSerializer.Meta.fields + ["description"]


class SupplierSerializer(serializers.ModelSerializer):
    class Meta:
        model = Supplier
        fields = ("id", "name")

модель:

class Site(models.Model):
    class Meta:
        ordering = ("name",)

    name = models.CharField(max_length=250)
    description = models.TextField(blank=True, null=True)
    supplier = models.ForeignKey(
        Supplier, on_delete=SET_NULL, blank=True, null=True, related_name="sites"
    )

1 Ответ

1 голос
/ 23 марта 2020

SerializerMethodField - это поле только для чтения. Таким образом, вы не можете использовать его для обновления данных. Вместо использования в вашем случае вы можете переопределить метод to_representation сериализатора:

class AdminSiteSerializer(serializers.ModelSerializer):

    class Meta:
        model = Site
        fields = [
            "id",
            "name",
            "supplier",
        ]


    def to_representation(self, instance):
        data = super().to_representation(instance)   
        if not instance.supplier:
            data['supplier'] = None
        data['supplier'] = SupplierSerializer(site.supplier).data
        return data
...