While making APIs, validating the request body is essential. It not only helps in pre-validating the request, but it also helps in handling fewer exceptions in the API call that might occur because of the invalid data type or the request body in the request.

Well, in this post, I will share how you may quickly validate your request body in Django with Django-Rest-Framework. I will add most of the variants of the JSON request body.

Expectations

The validator must not only check for the available keys in the request body but should also give a proper response about what is wrong in the body, even if it is about a nested JSON in the body. So if we list them, below are our expectations.

  1. Validate if it is a valid body or not
  2. Validate pre-defined formats for a key
  3. Validate nested JSON body
  4. Option to have an optional field, which if skipped should not throw any error
  5. Return the errors if any in the request

Sample Request

TLDR

You may find the sample project in my GitHub.

Solution

Django-Rest-Framework

I will use DRF alternatively in this post to quote Django-Rest-Framework. We will be using DRF for the validations. DRF is an excellent library for Django.

Let Code Talk

Assumptions: I assume you have set up the Django project.

Install DRF:

Either visit this or follow the below steps.

Run this command in the terminal in project root to install the Django-rest-framework.

pip install djangorestframework

Adding 'rest_framework' in INSTALLED_APPS in settings.py

INSTALLED_APPS = [ 
    ... 
    'rest_framework', 
]

Serializers

With DRF (Django-Rest-Framework), we may define serializers, you may read about a serializer here.

Create a serializers.py in the app root. We will define serializers for the request.

Import serializers from the DRF library.from rest_framework import serializers

Define Serializer

Create a serializer class and create class members with the name of the key in the request body. If the key is string_value , then create a class member with the same name and assign a serializer class to it. For example, if we want a String field, we have a class CharField in serializers just write it as below:class SomeSerializer(serializers.Serializer):
   string_value = serializers.CharField()

If we want the field not to be an optional field, we may pass therequired key to the serializer field. So, if we wish to that the string_value should be required, then we may update as:class SomeSerializer(serializers.Serializer):
   string_value = serializers.CharField(required=True)

If we want some nested JSON in the request body and validate that as well, then we may first define a serializer for the nested JSON and then use it in the Serializer. For example, if we want to have the below-nested JSON in a key.{
   "nested": true,
   "value": "test"
}

We will define a serializer for this first. And again, the rule follows, pass key to the field. And yet it may be nested again.class SomeNestedSerializer(serializers.Serializer):
   nested = serializers.BooleanField(required=True)
   value = serializers.CharField(required=True)

Finally, to have this JSON field in our main request body validation, we will have to add it in the SomeSerialierclass SomeSerializer(serializers.Serializer):
   string_value = serializers.CharField(required=True)
   dict_field = NestedSerializer(required=True)

It will only accept a dictionary key. If we want a list, we may pass many as True to the serializer as dict_field = NestedSerializer(required=True, many=True)

And, it will allow a list of dictionaries.

To learn more, read the docs.

TLDR, our serializer file should look like this.

Create Validators

Create a validators.py file in the required app. And you may use the below function.

Creating Views

Make a view as below.

Update URLs

Now add it in urls.py Make sure to import your views as views...
   path('api/', views.simple_api),
   ...

Now you are good to test your first validator.

Use any tool such as Postman to test this endpoint.

Try to access http://localhost:8000/api/ make a POST request and use the request body we defined earlier.

Now try to mess with the request body, and you will get a proper response about the error. For example, if I send an invalid url I will get this response.{
   "errors": {
       "url_field": [
           "Enter a valid URL."
       ]
   }
}

The best part is, it is smart. If we use an IntegerField and in the request, if we pass an integer as a string, then to it will work. So, for5 or '5' or 5.0 it will work the same. But if we give 'xyz' it will throw an error.

Give it a try in validating the request body. It will save a lot of time while making APIs that accept raw JSON.

Summary

Django-Rest-Framework is a great library for Django. It provides a lot of utility to Django. From serializers to ViewSets. If we want to validate a POST request with form-data. We may create a form in Django and validate the requests, whereas with raw JSON it is not the same. I tried a lot of dictionary validators before Django-Rest-Framework, but none of them were as useful, simple, and handy as DRF. So, DRF serializers are not only helpful in serializing a Django queryset, rather it is equally useful in validating a raw JSON request body or any Python dictionary with a very good error response generator which you may use straight away in your response body.

To conclude just make serializer as per your request body and let it handle the rest.

Could you buy me a book?

Kuldeep Pisda is writing software or blogs
An energetic and enthusiastic guy 👋 willing to learn from and help startups in technical aspects. I am a full-stack…