【问题标题】:Django Form (Checkbox) - unable to save dataDjango 表单(复选框) - 无法保存数据
【发布时间】:2017-09-27 16:43:03
【问题描述】:

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

这是我的模型:

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>

感谢所有帮助/建议。

【问题讨论】:

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


    【解决方案1】:

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

    其次,为了将CharField 呈现为CheckboxSelectMultiple 小部件,您的模型的字段声明必须更改。现在,您告诉subject 字段接受单个值(在'H''M''E' 值中),但是,通过您的表单,您尝试给它多个值([&amp;#39;H&amp;#39;, &amp;#39;M&amp;#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. 使用新字段名称 subjects 更新 forms.py 文件。

    【讨论】:

    • 感谢您的回复。通过在表单中​​显示选项时使用您的方法,它只显示一个带有标签“主题对象”的复选框,而不是所有主题。
    • 更新了我的答案。您必须首先创建 Subject 对象,当然还要在其中放置一个 __str__ 方法来打印名称而不是丑陋的 'Subject object'
    • 已将字段名称更改为主题并创建主题对象但仍无法显示。你能指导我正确创建主题对象吗?
    • 再次更新。
    • 很高兴我能帮上忙。如果你愿意,为了避免不小心重复的主题值(因为现在你可以输入另一个值HM,最终会有多个相同名称的值),你可以更改@的定义987654354@ 进入这个:name = models.CharField(max_length=2, unique=True, choices=SUBJECT_CHOICES, default=MATH)。当然,在那之后运行迁移;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    相关资源
    最近更新 更多