Django's formset can be difficult to understand, so I will try to explain it in a more understanbable way here.
What is it used for?
Let's say you are building a website which keeps track of users' daily activities. They can logon to your site and fill out a form with the following information:
- Date and time
- Activity name
Multiple activities can be recorded throughout a day. When users start to record for a new day, he should see an empty form with the aforementioned fields and an add button below the form to add more activities:
How it works?
Before getting into the implementation details, it is important to understand how formset works. The best way to learn it is to think out how you would implement it by hand.
CRUD is a good starting point to define what needs to be accomplished：
- Forms need to be created (i.e. create new form data that do not exist in the database)
- Forms need to be read (i.e. fill forms with existing data and display them to the user)
- Forms need to be updated (i.e. fetch existing data and save changes made to them)
- Forms need to be deleted (i.e. delete an existing form)
To accomplish any of these tasks, we need a way to keep track of forms. Thus, an ID is needed for each form. Also, when a form is deleted, we need a way to detect that. Thus, a form needs to be marked as deleted or not deleted.
How does Django do it?
To manage which form is which and mark them as deleted when neccessary, Django insert hidden input fields into the rendered HTML to help itself keeping track of the forms. Django inserts the following hidden data:
All of these hidden data, are added by the ManagementForm. You don't need to read about ManagementForm at the moment, just knowing which componment within Django is responsible for these is enough at this point.
To keep track of each form, Django also inserts hidden primary keys that are associated with existing forms:
To keep track of which form has been deleted, Django also inserts a hidden field:
The can_delete parameter is responsible for marking forms as deleted. I will explain this parameter later.
This post is long enough for a short read. I will explain more details about formset in the next blog post.