Search code examples
pythondjangodjango-modelsmany-to-manydjango-2.2

Save everything for new object except ManyToMany field in Django


I want to save object with ManyToMany relation. When I submit the form, all things save except field that have ManyToMany relation.

These are my files:

#Forms.py
class ExamForm(ModelForm):
    class Meta:
        model = Exam
        fields = '__all__'

#Models.py
class Exam(models.Model):
    questions = models.ManyToManyField(Question)
    title = models.CharField(max_length=250)
class Question(models.Model):
    title = models.CharField(max_length=250)
    answer = models.TextField(null=True, blank=True)

#Views.py
def add_exam(request):
    if request.method == "POST":
        form = ExamForm(request.POST)
        if form.is_valid():
            new_exam = form.save(commit=False)
            new_exam.save()
            return redirect('view_exam')
    else:
        form = ExamForm()
    template = 'add_exam.html'
    context = {'form': form}
    return render(request, template, context)

What is wrong with these codes?


Solution

  • As the docs explain, when you use commit=False the form cannot set the many-to-many relationship, because the object does not yet have an ID. So you would need to call the form's extra save_m2m() method:

    if form.is_valid():
        new_exam = form.save(commit=False) 
        # Add some modifications
        new_exam.save()
        form.save_m2m()
        return redirect('view_exam')
    

    But there is no reason to do this here. You should not use commit=False only to then save the model immediately. That is for when you want to modify the object before saving, which you're not doing here. Just save it directly:

       if form.is_valid():
            form.save()
            return redirect('view_exam')