Django表单(复选框) - 无法保存数据

时间:2017-04-29 18:40:51

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

我正在尝试显示一个表单(带有多个选择复选框)并将数据保存在数据库中。但是有一些问题。

这是我的模特:

class Preference(models.Model):

    CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')]
    BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')]
    SUBJECT_CHOICES = [('H', 'HINDI'), ('M', 'MATH'), ('E', 'ENGLISH')]

    class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False)
    board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False)
    subject = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default='M', blank=False)

我的表格:

class PreferenceForm(forms.ModelForm):
    class Meta:
        model = Preference
        fields = ['class', 'board', 'subject']
        widgets = {
            'board': forms.RadioSelect(),
            'subject': forms.CheckboxSelectMultiple()
        } 

我的观点:

def pref(request):
    form = PreferenceForm(request.POST or None)
    if form.is_valid():
        form.save()
        return render(request, 'website/thanks.html')
    else:
        print(form.errors)
        return render(request, 'website/pref.html', {'form': form})

它显示带有复选框的表单,但即使我选择单个选项,我也无法将该数据保存到数据库。

显示错误: - `

<li>Subject<ul class="errorlist"><li>Select a valid choice. [&#39;H&#39;, &#39;M&#39;] is not one of the available choices.</li></ul></li>

感谢所有帮助/建议。

1 个答案:

答案 0 :(得分:0)

首先,将模型中的class字段重命名为其他字段。 class是一个Python保留字,以后可能会给您带来麻烦。

其次,为了将CharField呈现为CheckboxSelectMultiple小部件,您的模型的字段声明必须更改。现在,您告诉subject字段接受单个值(在'H''M''E'值中),但是,通过您的表单,您尝试给它多倍的值([&#39;H&#39;, &#39;M&#39;],这意味着'H''M')。这是你的错误的原因。当你给它一个以上时,它期待一个值。

问题的解决方法是创建另一个模型,比如Subject,在该模型中声明SUBJECT_CHOICES和单个字段(比如说name)。然后在您的Preference模型中,将subject字段更改为ManyToManyField,而不是CharField。这样,subject模型的Preference字段就可以接受多个值。

这样的事情:

class Subject(models.Model):

    HINDI = 'H'
    MATH = 'M'
    ENGLISH = 'E'

    SUBJECT_CHOICES = [
        (HINDI, 'HINDI'),
        (MATH, 'MATH'),
        (ENGLISH, 'ENGLISH')
    ]

    name = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default=MATH)

    def __str__(self):
        return self.name


class Preference(models.Model):

    CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')]
    BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')]

    # RENAME THE class FIELD PLEASE, i.e class_number!
    class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False)
    board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False)
    # Notice the plural name of the field. Subjects, not subject, since we're expecting more than one value into this field.
    subjects = models.ManyToManyField(Subject)

最后:

  1. 不要忘记创建Subject个对象(通过管理员或./manage shell)。如果你使用管理员,那就相当简单了。如果您使用shell,请执行以下操作:

    from myapp.models import Subject
    
    [Subject.objects.create(name=choice[0]) for choice in Subject.SUBJECT_CHOICES]
    
  2. 使用新字段名forms.py更新subjects文件。