Django: ModelMultipleChoiceField won't save data
Asked Answered
Y

1

6

My modelform has a field with a ModelMultipleChoiceField that has a queryset to a Category object. The problem is the form submits, but the Category data doesn't save. Thoughts?

Many thanks!

Form:

class MealForm(forms.ModelForm):
  class Meta:
    model = Meal
    fields = ('category','date','time')

  category = forms.ModelMultipleChoiceField(
        label=_("Food style"),
        queryset=Category.objects.all(),
                                  required=True)

View

@login_required
def new_meal(request, template_name="meal/newmeal.html"):

  if request.method == 'POST':
    form = MealForm(request.POST)
    form.mom = request.user
    if form.is_valid():
      meal = form.save(commit=False)
      meal.mom = request.user
      meal.save()
      return HttpResponseRedirect('/meal/%d' % meal.id )
  else:
    form = MealForm()

  data = {
    'form': form,
    'add': True
  }

Models:

class Category(models.Model):

  name = models.CharField(default='',max_length=100)
  num_tags = models.IntegerField(default=0)

  def __unicode__(self):
          return "%s" % self.name
  class Meta:
    ordering = ['name']

class Meal(models.Model):
  category = models.ManyToManyField(Category)
Yep answered 13/1, 2011 at 19:57 Comment(0)
S
13

You need to use mymodelform.save_m2m() when you do commit=False on your ModelForm because m2m relationships cannot be saved without an ID (aka save(commit=True)).

An intermediary table (m2m) doesn't have an ID to reference if the parent model isn't saved first!

http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

@login_required
def new_meal(request, template_name="meal/newmeal.html"):

  if request.method == 'POST':
    form = MealForm(request.POST)
    form.mom = request.user
    if form.is_valid():
      meal = form.save(commit=False)
      meal.mom = request.user
      meal.save()
      form.save_m2m() # save m2m after meal has id

      return HttpResponseRedirect('/meal/%d' % meal.id )
  else:
    form = MealForm()

  data = {
    'form': form,
    'add': True
  }
Sharonsharona answered 13/1, 2011 at 20:5 Comment(4)
Ah thanks..the categories was an error I accidentally copied in. Removed.Yep
ah, then i will update my answer.. it's because you're doing commit=False and m2m can't be saved w/o an ID on modelDorso
It was bugging me for hours! And there's absolutely no error message (or warning)...Photomural
@Photomural glad this 6 year old post helped!!Dorso

© 2022 - 2024 — McMap. All rights reserved.