我想知道以下形式color
(多对多字段)如何通过CheckboxSelectMultiple
小部件的值填充。
#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.
答案 0 :(得分:4)
您正在执行form.save(commit=False)
,其中实际上并未在数据库中创建记录,因此无法存储M2M字段。保存表单后执行form.save_m2m()
。
或者从您的代码中,您可以在保存car.color.add()
后移动car
。而且您也不需要form.save(commit=False)
。
答案 1 :(得分:3)
你没有得到要显示的复选框,还是你试图摆脱的错误?如果是后者,请在保存表单时尝试删除commit=False
。
更新:
Color
模型未指定任何字段。给它一个,例如color = IntegerField(choices=COLOR_CHOICES)
。
在AddCar
形式中,如果错误则给出choices=Color.COLOR_CHOICES
- 你必须给它一个实际存在的对象元组(Color.COLOR_CHOICES只是代码常量)。你也可以使用ModelMultipleChoiceField,它接受一个queryset
参数,例如:
colors = forms.ModelMultipleChoiceField(queryset=Color.objects, widget=forms.CheckboxSelectMultiple(), required=False)
https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelmultiplechoicefield
答案 2 :(得分:2)
此错误是因为您尝试将相关对象保存到未保存的对象, 你有两个选择:
放commit=True
或之前:
for c in request.POST.getlist('color'):
car.color.add(c)
放:car.save()
如果您使用commit=False
,则表示该对象未保存。
但是,你不需要手动保存“颜色”,
做form.save_m2m()
会为你做,好吧,只有你的表格有
选择一个多领域。
编辑:
表单中的颜色字段不是很好,必须是ModelMultipleChoiceField
color = forms.ModelMultipleChoiceField(queryset=Color.objects.all())
查看文档: https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#inline-formsets