Как сделать пользовательский сериализатор, который может обрабатывать данные вложенных постов для конечной точки Create API?

В связи с уникальными потребностями бизнеса, мне необходимо настроить конечную точку Create API. Поведение по умолчанию в django-rest-framework выглядит следующим образом.

class Customer(models.Model):
    fieldA = models.IntegerField(null=True, blank=True)
    fieldB = models.CharField(max_length=5, blank=True)
    ... ...

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'

class CustomerListCreateAPIView(generics.ListCreateAPIView):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

разместите данные

{
    fieldA: 1,
    fieldB: 'some string'
}

он посылает ответ со статусом Created

{
    id: 1,
    fieldA: 1,
    fieldB: 'some string'
}

Однако я хочу размещать данные с вложенными данными, как это

{
    "customer": {
        "fieldA": 1,
        "fieldB": "some string"
    }
}

и ожидаемый ответ должен быть

{
    "customer": {
        "id": 1,
        "fieldA": 1,
        "fieldB": "some string"
    }
}

Как я могу архивировать это?

Вы можете создать ApiView и проверить все данные путем итерации. Если все данные достоверны, то создайте объекты.

Пример:



class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'

class CustomerListCreateAPIView(APIView):
    def post(self, request, *args, **kwargs):
        customers = request.data.get('customer', None)
        for customer in customers:
            validated_data = CustomerSerializer(data=customer)
            # if invalid Raise Validation error 
        objects = []
        for customer in customers:
            validated_data = CustomerSerializer(data=customer)
            customer = Customer.objects.create(validated_data)
            objects.append(customer.id)

        return Response(
            CustomerSerializer(Customer.objects.filter(id__in=objects), many=True).data)
    

Вот мой измененный метод. Он посылает вложенные сообщения об ошибках валидации.

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'


class CustomerView(generics.ListCreateAPIView):
    queryset = Customer.objects.all()

    def create(self, request, *args, **kwargs):
        customer = request.data.get('customer', None)
        if not customer:
            return Response("customer field is required", status=status.HTTP_400_BAD_REQUEST)

        serializer = CustomerSerializer(data=customer)
        serializer.is_valid(raise_exception=False)
        if serializer.errors:
            error = {
                'customer': serializer.errors
            }
            return Response(error, status=status.HTTP_400_BAD_REQUEST)

        data = serializer.save()
        headers = self.get_success_headers(serializer.data)
        return Response(data, status=status.HTTP_201_CREATED, headers=headers)

Ошибки валидации:

{
    "customer": "customer field is required"
}

{
    "customer": {
        "fieldA": ["filedA is required"],
    }
}

Надеюсь, это поможет другим

Вернуться на верх