【问题标题】:How to save Many To Many field with Multiple Checkboxes in Django Form如何在 Django 表单中使用多个复选框保存多对多字段
【发布时间】:2012-07-23 11:06:01
【问题描述】:

我想知道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.

【问题讨论】:

    标签: django django-models django-forms django-views


    【解决方案1】:

    此错误是因为,您正在尝试将相关对象保存到未保存的对象中, 你有两个选择:

    输入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

    【讨论】:

    【解决方案2】:

    您是没有显示复选框,还是您要消除的错误?如果是后者,请在保存表单时尝试删除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

    【讨论】:

    • 复选框正在显示,我在视图中获取了选定的值,但我无法保存它们。删除 commit=False 后出现此错误:在表“cars_car_color”上插入或更新违反外键约束
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2018-09-30
      • 2020-05-25
      • 1970-01-01
      • 2017-01-17
      • 2012-01-10
      • 2023-04-02
      • 2019-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多