我正在尝试显示一个表单(带有多个选择复选框)并将数据保存在数据库中。但是有一些问题。
这是我的模特:
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. ['H', 'M'] is not one of the available choices.</li></ul></li>
感谢所有帮助/建议。
答案 0 :(得分:0)
首先,将模型中的class
字段重命名为其他字段。 class
是一个Python保留字,以后可能会给您带来麻烦。
其次,为了将CharField
呈现为CheckboxSelectMultiple
小部件,您的模型的字段声明必须更改。现在,您告诉subject
字段接受单个值(在'H'
,'M'
和'E'
值中),但是,通过您的表单,您尝试给它多倍的值(['H', 'M']
,这意味着'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)
最后:
不要忘记创建Subject
个对象(通过管理员或./manage shell
)。如果你使用管理员,那就相当简单了。如果您使用shell
,请执行以下操作:
from myapp.models import Subject
[Subject.objects.create(name=choice[0]) for choice in Subject.SUBJECT_CHOICES]
使用新字段名forms.py
更新subjects
文件。