8

I'm submitting a JSON to a django view with AJAX. The JSON looks like the following:

{
   "code":"9910203040", // required
   "name":"Abc", // required
   "payments":[
      {
         "amount":300, // required
         "name":"efg", // required,
         "type": 2 // can be empty
      },
      {
         "amount":100,
         "name":"pqr",
         "type": 3
      }
   ]
}

The payments list can be of any size. How can I validate this in Django? Is it possible to use Django Forms to validate this? If it was Spring, I would create Request classes and use annotations on fields but can't figure out how to do this in Django.

ABN
  • 1,024
  • 13
  • 26
Nayan
  • 1,521
  • 2
  • 13
  • 27
  • Try `json.loads()`: https://stackoverflow.com/a/5508552 and [Django validators](https://docs.djangoproject.com/en/3.1/ref/validators/#module-django.core.validators). – djvg Mar 08 '21 at 10:10

4 Answers4

21

You can use django rest framework to validate request data as mentioned by @zaphod100.10 ,

here is the serializer you can use to validate-

from rest_framework import serializers

class PaymentSerializer(serializers.Serializer):
    amount = serializers.IntegerField(required=True, min_value=0, null=True)
    name = serializers.CharField(required=True, max_length=128)
    type = serializers.IntegerField(required=True, min_value=0)

class ValidateFormSerializer(serializers.Serializer):
    code = serializers.CharField(required=True, max_length=32)
    name = serializers.CharField(required=True, max_length=128)
    payments = serializers.ListField(child=PaymentSerializer)

You need like this to validate it in the view section -

 import ValidateFormSerializer

# add this snippet in your view section
 valid_ser = ValidateFormSerializer(data=request.data)
 if valid_ser.is_valid():
       post_data = valid_ser.validated_data
 else:
      print(valid_ser.errors)

Let me know, if it is enough to solve your problem.

tom
  • 3,720
  • 5
  • 26
  • 48
  • I'm not using django rest framework in my project. Is there any alternate? – Nayan May 20 '17 at 12:00
  • check https://docs.djangoproject.com/en/1.11/ref/forms/validation/ , is there any specific reason for not using django rest framework ? – tom May 20 '17 at 12:03
  • Not actually. I've a single view function that accepts the complex JSON request like the above. All other views are plain form submissions. I'm just curious to know is there an elegant way to do this with django builtin api. – Nayan May 20 '17 at 12:07
  • 1
    I'm using django rest-framework in my project. Thank you for your answer. However I've edited it a bit to match current api documentation. – Nayan May 21 '17 at 17:42
3

There are a number of ways to validate json. I would list following:

  1. Marshmallow
  2. Schema Validation

Let me know if you need any help in using these

Mohammad Mustaqeem
  • 1,034
  • 5
  • 9
0

you can use django rest framework [1] it is very good for handling json requests.

for validating data you can use a serializer or a django form.

using a form:

@api_view(['POST'])
def my_view(request):
    payments = request.data.pop('payments', [])
    # validate the main object
    form = MyForm(request.data)
    if form.is_valid():
        obj = form.save()
    else:
        raise APIException(form.errors)
    for pdata in payments:
        form = PaymentForm(pdata)
        if form.is_valid():
            # your code
        else:
            raise APIException(form.errors)  
    return Response()

[1] http://www.django-rest-framework.org/

zaphod100.10
  • 3,331
  • 24
  • 38
0

You can use formsets. For example:

class UserForm(Form):
    code = forms.CharField()
    name = forms.CharField() 

class PaymentForm(Form):
    amount = forms.CharField()
    name = forms.CharField()
    type = forms.CharField()

class TestView(View):
    def post(self, request):
        response_data={}
        json_data=json.loads(request.body)
        UserFormSet = formset_factory(UserForm)
        userformset = UserFormSet(initial=[{'code' : json_data['code'], 'name' : json_data['name']}])
        PaymentFormSet = formset_factory(PaymentForm)
        paymentformset = PaymentFormSet(initial=json_data['payments'])
        for userform in userformset:
            #do something
        for paymentform in paymentformset:
            #do something
        return JsonResponse(response_data)
ABN
  • 1,024
  • 13
  • 26