Tech Incent
DjangoDjango Form

How to create Django form?

how-to-create-django-form

Django’s form functionality can simplify and automate vast portions of work like data prepared for display in a form, rendered as HTML, edit using a convenient interface, returned to the server, validated, and can also do it more securely than most programmers would be able to do in code they wrote themselves.

Django manages three parts of the work involved with the forms:

  1. Preparing and restructuring data to make it ready for rendering
  2. Creating HTML forms for the data
  3. Receiving and processing submitted forms and dab from the client

Note: Form example progress, I am going to use the product app.

Create django form using forms class

To create a Django form we have to create new file forms.py inside your product app. Now we can create a Django form with the name of ProductForm inside the product/forms.py file.

from django import forms

class ProductForm(forms.Form):
    STATUS = (
        ('published', "Published"),
        ('pending', 'Pending'),
        ('rejected', 'Rejected'),
    )
    name = forms.CharField(max_length=250, label='Product Name')
    description = forms.CharField(widget=forms.Textarea())
    status = forms.ChoiceField(choices=STATUS)
    is_active = forms.BooleanField()

Let’s explain ProductForm. First, we define ProductForm class which must extend Django Forms. Now you see there is a STATUS tuple set that was used as a status choices field.
You notice that there are four forms field declared. Which was left side contains the field name by default it’s also label name. But you change the label name with the attribute label. By the way the right-side contain field configurations. In the below field structure.

field_name/label_name = Forms.FieldType(attributes)

Form all FieldsTypes

    'Field', 'CharField', 'IntegerField',
    'DateField', 'TimeField', 'DateTimeField', 'DurationField',
    'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
    'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
    'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
    'SplitDateTimeField', 'GenericIPAddressField', 'FilePathField',
    'JSONField', 'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField',
    'UUIDField',

Create view for ProductForm

Go to product/view.py file and create product_form function, which helps Django form to render HTML template

from django.shortcuts import render
from .forms import ProductForm

def product_form(request):
    form = ProductForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            # save data as you want
            pass
    ctx = {
        'form': form
    }
    return render(request, 'product/product_form.html', ctx)

So in the product_form view, you need to declare form instance. form request.

Don’t forget to map url

Create an urls.py file inside your product app directory.

Note: Make sure you also map product/urls.py with app urls.py

from django.urls import path
from .views import product_form

urlpatterns = [
    path('form', product_form, name="product_form")
]
# In your project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('product/', include('product.urls')),
]

Render form in html template

Make a product_form.html template inside templates/product directory and render product form.

<form action="{% url 'product_form' %}" method="post" novalidate>
  {% csrf_token %}
  {{ form.as_p }}
  <button class="btn btn-success px-4" type="submit">Submit</button>
</form>

Explain rendering, with Django build-in methods, all form fields will automatically render in HTML. But you need to provide a csrf_token token for security, and the form button also provides manually.

Note: The novalidate is a boolean attribute in form. The novalidate attribute prevents forms from running their validation logic when the form is submitted. In our example, we are going to raise required field errors. This will prevent us from looking at the actual validity of the server-side data and exploring faulty states of the form rendering.

Render form with Django default and built-in method:
  • {{ form.as_p }}: The as_p method provides rendering to the template in each case with each p tag wrapper.
  • {{ form.as_ul }}: The as_ul method provides rendering to the template in each case with each li tag wrapper.
  • {{ form.as_table }}: The as_p method provides rendering to the template in each case with each tr tag wrapper.
  • {{ form }}: without any method, Django renders the form as none of the tag wrapper, just label, and input value
render-form-as-p
Form view

Render django form manually

<form action="{% url 'product_form' %}" method="post" novalidate>
  {% csrf_token %}
  {% if form.non_field_errors %}
    <ul>
    {% for error in form.non_field_errors %}
      <li>{{ error }}</li>
    {% endfor %}
    </ul>
  {% endif %}
  {% for hidden_field in form.hidden_fields %}
    {% if hidden_field.errors %}
     <ul>
      {% for error in hidden_field.errors %}
       <li>(Hidden field {{ hidden_field.name }}) {{ error }}</li>
      {% endfor %}
     </ul>
    {% endif %}
    {{ hidden_field }}
  {% endfor %}

  {% for field in form.visible_fields %}
  <p>
    {{ field.label_tag }}
    {{ field.errors }}
    {{ field }}
    {{ field.help_text }}
  </p>
  {% endfor %}
  <button class="btn btn-success px-4" type="submit">Submit</button>
</form>

Another important topic, Django bound forms and unbound forms

Bound Form:

The form contains data set of data, it calls bound form. Bound form capable of validating that data. And Bound form renders the form as HTML with the data displayed in the HTML. here is a bound form example:

data = {
  'name': 'Mens winter boots',
  'desciption': 'Some description',
  'status': 'published',
  'is_active': True
}
form = ProductForm(data)

Unbound:

Unbound form means it does not contain data. So it cannot do validation (because there’s no data to validate!), but it can still render the blank form as HTML.

form = ContactForm()

Related posts

How to delete file when models instance is delete or update in Django?

Sajal Mia

Explained Django inline formset factory with example?

Sajal Mia

How to set up django react together ?

Sajal Mia

How to work with django ajax requests ?

Sajal Mia

How to deploy django and react in heroku ?

Tech Incent

How to setup django static and media file in aws s3 ?

Sajal Mia