This is a plain vanilla form built in Django. It allows a website user to "contact" the website; hence, the name. Forms are used for data entry and modification. Django gives developers many handy tools to simplify working with forms. But many Django devs are still afraid to write and work with forms, and they lean on the Django Admin perhaps too much.
Add LOLcat image that sez halp!
Here is what a Model Form implementation looks like in practice.
Here are some examples of how you can override or add to a Model Form. Django provides several ways to easily customize a Model Form, including the fields attribute, the exclude attribute, and the widgets attribute.
Note that the formset defaults to a table-based output. This can be modified by manually looping through the formset in the template and outputting using any of the default Django formats. TIP: Formsets do write in a "management" form in your template. If you are doing any fancy JS stuff, you might need to manipulate this management form.
Factories are common design patterns in many languages. Factories can and do work in Python and in Django forms.
The form on top is a snippet of a form made dynamic by overriding the __init__ function. For most types of form customization, this is the preferred way of handling dynamic forms. The example on bottom shows what a factory version of the same form would look like.
This example of a dynamic form shows a solution to another common problem. The goal is to have additional data available for validating some part of the submitted data. (In this case, for limiting results of the search that is being performed.) This technique is also very handy for generating choice tuples based on custom queries.
Always try to isolate logic in places that is reusable. Forms are good places to keep reusable code elements, and the form.save() method is one of the most valuable.
By isolating functionality like this, it becomes possible to easily adapt to other system structures. For example, adding Message Queues to functions is very easy if you properly abstract code away from your Views.