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

Django Form (Checkbox) - unable to save data

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

这是我的模型:

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})

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

显示错误:- `

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

感谢所有help/suggestions,谢谢。

首先,将模型中的 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。这样,Preference 模型的 subject 字段将能够接受多个值。

像这样:

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