How to Initialize Default Multiple Choice Field in Django Form?

How to Initialize Default Multiple Choice Field in Django Form?

In the earlier Django tutorial, I have explained- how to create a model, form, and template.

In this tutorial, we are going to learn how to create a Django form with a multi-choice field (multiple choice options) and select initial values by default.

Here is a short glimpse of the Django form we are going to create in this tutorial.

multi select checkbox in Django with default initial values

I will explain this with an example.

Create Django Form with MultipleChoiceField

Follow the steps one by one.

Step 1: Create model with CharField()

We are going to create a model which has a field of type CharField.

Update models.py.

from django.db import models

class Contact(models.Model):
    prefered_contact= models.CharField(max_length=120, choices=CONTACT_PREFERENCE, default='')

Step 2: Define Django Form

Create a Django form with the form field of type MultipleChoiceField.

Here choices are the options for the multi-select checkbox.

Update forms.py.

CONTACT_PREFERENCE = [
    ('email', 'Email'),
    ('chat', 'Chat'),'
    ('call', 'Call'), 
]

class ContactForm(forms.ModelForm):
    prefered_contact = forms.MultipleChoiceField(
        choices=CONTACT_PREFERENCE, 
        widget=forms.CheckboxSelectMultiple()
    )

    class Meta:
        model = Contact
        fields = ('prefered_contact',)

Step 3: Show Django Form in Template

You can use a Django template tag to display the HTML form.

{{ form.as_p }}

It will show the Django form with a multi-select checkbox. This is pretty easy.

Now, what happens when you submit the form?

When you submit the form, the values of the selected options are stored as a list of values. But, this list is saved in the model as a Python string. You can check that in the Django admin panel.

Select Default Checkbox Options in Django Form

In this Django form, we want to show the default options selected.

In the above example, when the user opens the form, the ’email’ and ‘chat’ options should be selected by default.

Update the Django view by setting the initial values for the checkbox field while creating an instance of the Django form. The initial value to the multiple-choice fields should be the list of values.

def land_demand_form(request):
    form = ContactForm(request.POST or None, initial={"prefered_contact": ['email', 'chat']})
    context= {'form': form}

Now, it will show the initial values (’email’ and ‘chat’) populated on the Django form.

Note: Property initial works when you use the {{ form.as_p }} template tag to create the Django form. If you are customizing a Django form template manually, this method does not work.

In that case, pass the list of the default selected options as a new context variable (says ‘selected_contact’) to the Django template.

This is a bit tricky.

def land_demand_form(request):
    form = ContactForm(request.POST or None)
    context= {'form': form, selected_contact=['email', 'chat']}

And update the Django template to show the multi-select checkbox options.

{% for value, text in form.prefered_contact.field.choices %}
    <label for="id_prefered_contact_{{ forloop.counter0 }}">
    <input type="checkbox" name="prefered_contact" value="{{ value }}" id="id_prefered_contact_{{ forloop.counter0 }}" {% if value in selected_contact %} checked="checked"{% endif %}> {{ text }}
    </label>
    <br>
 {% endfor %}

You are done!

How to create a Django form to update MultipleChoiceField fields?

If you are allowing users to update or edit the form, fetch the object from the model (one that the user has already submitted). It will return the Python list of the earlier selected options.

Now, instead of hardcoding the initial (default) value, pass the list of selected options and populate them in the HTML form.

Update the Django view as follow.

import ast

def land_demand_form(request):
    obj= get_object_or_404(Contact, user=request.user)
    res = ast.literal_eval(obj.prefered_contact)
    form = ContactForm(request.POST or None, initial={"prefered_contact": res})
    context= {'form': form}

Here, obj.pregeted_contact returns, the string representation of the list. We are using ast module to convert the string representation of the Python list into the actual Python list.

With this, users can edit or modify the earlier selected options.

If you have any doubt, let me know in the comment section below.

2 Comments

  1. Hi, Aniruddha,

    It is good tutorial.

    But, variable CONTACT_PREFERENCE doesn’t seem to defined in Contact model class

Leave a Reply

Your email address will not be published. Required fields are marked *