How to save Many To Many field with Multiple Checkboxes in Django Form
Solution 1
Are you not getting the checkboxes to show, or is it the error you're trying to get rid of? If the latter, try removing the commit=False
when saving the form.
Update:
The Color
model is not specifying any fields. Give it one, e.g. color = IntegerField(choices=COLOR_CHOICES)
.
In AddCar
form, giving choices=Color.COLOR_CHOICES
if wrong - you must give it a tuple of objects that actually exists (Color.COLOR_CHOICES are just code constants). Also you probably should use ModelMultipleChoiceField, which takes a queryset
parameter, e.g.:
colors = forms.ModelMultipleChoiceField(queryset=Color.objects, widget=forms.CheckboxSelectMultiple(), required=False)
https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelmultiplechoicefield
Solution 2
You are doing form.save(commit=False)
in which does not actually creates record in DB and due to which it cannot store M2M fields. Do form.save_m2m()
after you save form.
Or from your code, you can move car.color.add()
after you have saved the car
. And also you don't need to have form.save(commit=False)
.
Solution 3
This error is because, you are trying to save related objects to an object that isnt saved, you are two options:
put commit=True
or before:
for c in request.POST.getlist('color'):
car.color.add(c)
put: car.save()
If you use commit=False
, that objects is not beign saved.
But, you dont need save manually the "colors",
doing form.save_m2m()
will do it for you, well, only if your form has
a manytomany field to choise.
EDIT:
Your color field within form, isnt well formed, must be a ModelMultipleChoiceField
color = forms.ModelMultipleChoiceField(queryset=Color.objects.all())
see docs: https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#inline-formsets
howtodothis
Updated on June 04, 2022Comments
-
howtodothis almost 2 years
I would like to know how in the following form
color
(many-to-many field) can be populated by values fromCheckboxSelectMultiple
widget.#models.py
class Color(models.Model): RED = 1 BLACK = 2 COLOR_CHOICES = ( (RED, _('Red')), (BLACK, _('Black')), ) name = models.CharField(_('Color'), max_length=512, choices=COLOR_CHOICES, blank=True) class Car(models.Model): color = models.ManyToManyField(Color, blank=True, null=True) def save(self): self.slug = slugify(self.name) super(Car, self).save()
#forms.py
class AddCar(forms.ModelForm): color = forms.MultipleChoiceField( choices=Color.COLOR_CHOICES, widget=forms.CheckboxSelectMultiple(), required=False )
#view.py
def add(request): if request.method == 'POST': form = AddCar(request.POST) ... if form.is_valid(): car = form.save(commit=False) for c in request.POST.getlist('color'): car.color.add(c) car.save() form.save_m2m() return redirect('/')
#error
'Car' instance needs to have a primary key value before a many-to-many relationship can be used.