Multiple Select with Django Forms

To use a multiple select with Django ModelChoiceField for forms, you should use the ModelMultipleChoiceField instead. This field allows you to select multiple options from a queryset of model instances.Here’s an example of how to use ModelMultipleChoiceField with a multiple select widget in a Django form:

  1. Create your models: Define your models in the models.py file. In this example, we have a Tag model and a Post model with a many-to-many relationship.
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    tags = models.ManyToManyField(Tag)

    def __str__(self):
        return self.title
  1. Create your form: In your forms.py file, create a form using ModelMultipleChoiceField for the tags field. Set the queryset attribute to the model instances you want to display as choices, and use the forms.SelectMultiple widget.
from django import forms
from .models import Post, Tag

class PostForm(forms.ModelForm):
    tags = forms.ModelMultipleChoiceField(
        queryset=Tag.objects.all(),
        widget=forms.SelectMultiple,
    )

    class Meta:
        model = Post
        fields = ['title', 'content', 'tags']
  1. Create your view: In your views.py file, create a view that handles the form submission and rendering.
from django.shortcuts import render, redirect
from .forms import PostForm

def create_post(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('success_url')
    else:
        form = PostForm()
    return render(request, 'create_post.html', {'form': form})
  1. Create your template: In your template file, render the form fields, including the multiple select field for the tags.
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Submit">
</form>

By following these steps, you can create a Django form with a multiple select widget using ModelMultipleChoiceField. Users will be able to select multiple options from the queryset of model instances when submitting the form.

If the tags are not being saved with the form, it might be because the commit=False option is used when calling form.save(). When using commit=False, the form saves the instance without committing it to the database, which means that the ManyToMany relationships are not saved yet. To save the tags, you need to call the save_m2m() method on the form after saving the instance.Update the create_blog view in your views.py file as follows:

from django.shortcuts import render, redirect
from .forms import BlogForm

def create_blog(request):
    if request.method == 'POST':
        form = BlogForm(request.POST)
        if form.is_valid():
            blog = form.save(commit=False)
            blog.save()
            form.save_m2m()  # Save the ManyToMany relationships
            return redirect('blog_detail', blog_id=blog.id)
    else:
        form = BlogForm()

    return render(request, 'create_blog.html', {'form': form})

In this updated view, the form.save(commit=False) line saves the instance without committing it to the database. After calling blog.save(), the form.save_m2m() method is called to save the ManyToMany relationships, including the tags associated with the blog post.Now, when you submit the form, the tags should be saved along with the blog post.

I hope this was helpful

Thanks for your time

Jesus Saves

By Jesse E.Agbe(JCharis)

Leave a Comment

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