5

我想知道如何在以下表单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('/')

#错误

'Car' instance needs to have a primary key value before a many-to-many relationship can be used.
4

3 回答 3

4

您正在做form.save(commit=False)的实际上并没有在 DB 中创建记录,因此它无法存储 M2M 字段。form.save_m2m()保存表单后执行。

或者从您的代码中,您可以car.color.add()在保存car. 而且你也不需要拥有form.save(commit=False).

于 2012-07-25T04:20:24.867 回答
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

于 2012-07-25T04:15:14.810 回答
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

于 2012-07-25T04:18:53.693 回答