Debido a las necesidades comerciales únicas, tengo que personalizar el punto final Crear API. El comportamiento predeterminado en django-rest-framework es así.
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 = CustomerSerializerpublicar datos
{ fieldA: 1, fieldB: 'some string' }envía responder con el estado Creado
{ id: 1, fieldA: 1, fieldB: 'some string' }Sin embargo, quiero publicar datos con datos anidados y validar
{ "customer": { "fieldA": 1, "fieldB": "some string" } }Los datos de respuesta esperados deben ser
{ "customer": { "id": 1, "fieldA": 1, "fieldB": "some string" } }También la validación debería mostrar mensajes de error anidados
{ "customer": "customer field is required" } { "customer": { "fieldA": ["filedA is required"], } }¿Cómo puedo archivar esto?
Puede crear un ApiView y validar cada dato individual iterando. Si todos los datos son válidos, cree los objetos.
Ejemplo:
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)Aquí está mi enfoque revisado. Crea una nueva instancia utilizando el serializador y envía mensajes de error de validación anidados.
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: raise serializers.ValidationError({'customer': 'customer field is required'}) 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)Errores de validación:
{ "customer": "customer field is required" } { "customer": { "fieldA": ["filedA is required"], } }Espero que esto ayude a otros.