Google Summer of Code - Formset Improvement

About the Project

I worked on the “Form” layer of Django, specifically on FormSet, ModelFormSet, and InlineFormSet. This project aims to improve the above classes, add new features to them, thus enhancing their functionality and ease of use.

Django currently has a formset class which is used as a collection instance for the forms. It’s a layer of abstraction which makes it easier to work with multiple forms. Similarly, ModelFormSet and InlineFormSet are used to handle models and related models respectively.

Goal of the Project

The broad goal was to have an error-free Formset and close all the tickets related to formset. The end goal of this project was to address as many issues as possible and also make the formsets more user-friendly.

I aimed to give the user more control over the individual forms in the formset, by enabling the user to pass different arguments for __init__() and save() methods of each form. The next goal was to enable the user to use formsets for edit only purpose, by implementing a robust framework which will disable creating of new model objects, instead of workarounds which can’t do much in case of forged POST requests. After that, the next goal was to add some new features to formset like pagination, declarative syntax of ModelFormSet & InlineFormSet.

Technical description

The project as a whole can be divided into smaller independent task. This task were actually the bugs and feature requests that I planned to compelete.

Initial Tasks

Some of this issues included documentation bugs which helped me to get started and understand the code better (For e.g. Task 1). After that I started with implementation of passing custom arguements to the Formset class. This required understanding the BaseFormSet class. But I figured that this feature was already implemented and could have been achieved with something which was already present, just needed some documentation (See Task 2).

Declarative Syntax for the FormSet, ModelFormSet and InlineFormSet

This task is the highlight of my project. The task was to add declarative syntax support for the FormSet class. The declarative syntax is something which one can regularly see in the Model or Form classes of Django. Example of the same is shown in the below example

class Musician(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    instrument = models.CharField(max_length=100)

The way formsets were created was using formset_factory(), which when passed the desired inputs created a FormSet class and returned it. But if you lets say need to have an extra function in your MyFormSet then you would first have to derive a class from the BaseFormSet then pass it as the argument to formset_factory which will then return the desired class with desired methods.

This task involved learning about Metaprogramming, understanding how python classes are actually created, implementing the declarative syntax and most importantly documentation and writing tests. You can read about the full task in detail here.

Wrapping up

After the above tasks, I also fixed some more bugs. Which include things like implementing a secure way to edit only the queried subset of the databse model. This reduced the risk of any adversary manipulating form data in order to edit the database enteries which they are not authorized to do sp. This invovled implementing some checks in order to restrict that only the table enteries which are queried will be modified.

You can read more about my whole experience of the project in detail in this blog