• Django Form is a tool for validating HTML input data.
  • DRF Serializer is a tool for validating and transforming JSON API data.
  • Both tools share very similar is_valid() methods, validated data access, and error handling flows.
  • ModelForm and ModelSerializer also resemble each other in their model-based automatic field generation and saving structures.

Similarities Between Django Forms and DRF Serializers

When working with Django, we're often supported (and sometimes challenged) by two crucial components: Django Form and DRF (Django REST Framework) Serializer. Here, we've compiled their striking similarities.

Despite operating in different arenas (web pages vs. APIs), these two tools share an eerily similar fundamental role and structure: "safely validating external data for internal use, and elegantly packaging internal data for external output."

Symbolic image of serializer and form


1. Role Comparison at a Glance

To put it simply, they act as 'security guards and guides' at the entrance of a department store.

  • Django Form: Primarily operates in the world of HTML web pages. It inspects user-entered data (Form Data) from the browser to ensure its validity, and if errors occur, it kindly renders a message like "Please re-enter" on the screen.
  • DRF Serializer: Primarily functions in the API world, where JSON data is exchanged. It converts JSON data sent by mobile apps or front-end frameworks (like React, Vue) into Python objects, and conversely, elegantly packages (serializes) database data into JSON.
Feature Django Form (Web Page-Centric) DRF Serializer (API-Centric)
Input HTML Form -> Python Dictionary (cleaned_data) JSON String -> Python Dictionary (validated_data)
Data Validation Call is_valid() Call is_valid()
Output Python Object -> Rendered as HTML Tag (<input>) Python Object -> Converted to JSON String (Serialization)

2. Why So Similar? Three Structural Resemblances

The developers who created DRF found Django Form's structure so excellent that they largely benchmarked it to build Serializers. Consequently, their code structure and usage are strikingly similar, like fraternal twins.

① Identical Field Definition Methods

The way they specify the format for incoming data is an exact replica.

  • Django Form:
from django import forms

class UserForm(forms.Form):
    username = forms.CharField(max_length=100)
    email = forms.EmailField()
    age = forms.IntegerField()
  • DRF Serializer:
    from rest_framework import serializers

    class UserSerializer(serializers.Serializer):
        username = serializers.CharField(max_length=100)
        email = serializers.EmailField()
        age = serializers.IntegerField()

The logic for declaring fields is completely identical, except for forms being replaced by serializers.

② Identical Validation and Data Access Methods

The method flow for checking data safety and accessing validated data is consistent.

  1. Validation: Both methods involve calling if form.is_valid(): or if serializer.is_valid(): after providing the data.
  2. Accessing Validated Data: Clean data, after validation, is stored in a dictionary: form.cleaned_data for Forms and serializer.validated_data for Serializers. The names are slightly different, but the functionality is the same.
  3. Error Checking: If validation fails, form.errors or serializer.errors provides error messages in a dictionary format, indicating what went wrong.

③ Integration with Models (ModelForm vs. ModelSerializer)

The core of Django is its integration with the DB (Model). Both tools feature 'cheat code' classes that automatically generate fields based on a model.

  • Django ModelForm:
    class MyModelForm(forms.ModelForm):
        class Meta:
            model = MyModel
            fields = ['title', 'content']
  • DRF ModelSerializer:
    class MyModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = MyModel
            fields = ['title', 'content']

The syntax for specifying which model to base on and which fields to use, via the internal Meta class, is eerily identical. Thanks to this, calling the save() method results in the automatic creation (create) or modification (update) of data in the DB, also identically.


Concluding Thoughts

  • Django Form acts as an interpreter between HTML and Python, handling data validation.
  • DRF Serializer acts as an interpreter between JSON and Python, handling data validation.

If you've worked with Django Forms in the past, you can think of DRF Serializers as "Forms that handle JSON instead of HTML," and you'd be over 90% correct. Conversely, if you've encountered Serializers first, Forms will also be easy to understand.

However, I believe many backend engineers, despite recognizing the significant similarities between these two tools, feel comfortable with Serializers but uncomfortable with Forms, which were their foundation. I certainly feel that way.

Have you ever deeply considered why you might feel this way? In the next installment, I plan to discuss why Django Forms, despite their resemblance to Serializers, often cause discomfort the more you use them.

If this article was helpful, please give it a like and look forward to the next one!