【问题标题】:Django Form Error: Select a valid choice. 29 is not one of the available choicesDjango 表单错误:选择一个有效的选项。 29 不是可用的选择之一
【发布时间】:2012-05-13 20:27:29
【问题描述】:

表单 HTML

<form action="" method="post" class="form-horizontal"><div style="display:none"><input type="hidden" name="csrfmiddlewaretoken" value="6b3d58df7bd4f6d10975462aaf3bd42d"></div>
        <input type="hidden" name="paper" value="5225" id="id_paper"><fieldset><div id="div_id_priority" class="control-group">
    <label class="control-label" for="id_priority">Priority</label>
    <div class="controls">
        <select name="priority" id="id_priority">
<option value="1" selected="selected">Primary</option>
<option value="2">Secondary</option>
</select>


        <p class="help-block"><span class="help_text">Primary - 1st Choice. Secondary - 2nd Choice.</span></p>

    </div>
</div> <!-- /clearfix -->
<div id="div_id_topic" class="control-group">
    <label class="control-label" for="id_topic">Topics</label>
    <div class="controls">
        <select name="topic" id="id_topic">
<option value="6">A</option>
<option value="7" selected="selected">B</option>
<option value="9">C</option>
</select>


    </div>
</div> <!-- /clearfix -->
<div id="div_id_subtopic" class="control-group error">
    <label class="control-label" for="id_subtopic">SubTopics</label>
    <div class="controls">
        <select name="subtopic" id="id_subtopic">
<option value="29">KEEPER</option></select>

        <span class="help-inline">Select a valid choice. 29 is not one of the available choices.</span>


    </div>
</div> <!-- /clearfix -->
</fieldset>

        <div class="form-actions">
            <button type="submit" class="btn btn-primary">Add</button>
        </div>

    </form>

查看

@login_required
@event_required
def add_topic(request, paper_id):
    event = request.event
    paper = get_object_or_404(SubmissionImportData, pk=paper_id)
    form = TopicForm(request.POST or None, event=event, paper=paper)
    print request.POST  # i see subtopic here
    print form.errors
    if request.method == 'POST' and form.is_valid():
        cd = form.cleaned_data
        subtopic = request.POST.get('subtopic')
        if subtopic:
            subtopic_obj = get_object_or_404(SubTopic, pk=subtopic)
        else:
            subtopic_obj = None

        paper_topic = PaperTopic.objects.get_or_create(
                submission_import_data=paper,
                priority=cd['priority'],
                topic=cd['topic'],
                sub_topic=subtopic_obj)[0]

        msg = 'Topic Successfully Added'
        messages.success(request, msg)
        url = reverse('submissions_nonadmin_view_topic',
                args=[event.slug, paper.id])
        return redirect(url)

表格类

class TopicForm(BootstrapForm):
    topic = forms.ModelChoiceField(label='Topics',
            queryset=None, required=False, empty_label=None)
    subtopic = forms.ChoiceField(label='SubTopics',
            widget=forms.Select(attrs={'disabled': 'disabled'}),
            required=False)
    paper = forms.IntegerField(widget=forms.HiddenInput())
    priority = forms.ChoiceField(label='Priority',
            choices=PaperTopic.PRIORITY, required=False)

    class Meta:
        fields = (
                'priority', 'topic', 'subtopic', 'paper',
                )
        layout = (
                Fieldset('', 'priority', 'topic', 'subtopic', 'paper',),
                )

    def __init__(self, *args, **kwargs):
        event = kwargs.pop('event')
        #paper_topic = kwargs.pop('paper_topic')
        paper = kwargs.pop('paper')
        super(TopicForm, self).__init__(*args, **kwargs)
        self.fields['paper'].initial = paper.id
        self.fields['topic'].queryset = Topic.objects.\
                filter(setting=event.setting)
        self.fields['priority'].help_text = 'Primary - 1st Choice. Secondary - 2nd Choice.'
        #if paper_topic:
            #self.fields['topic'].initial = Topic.objects.\
                    #get(pk=paper_topic.topic.id)

    def clean(self):
        '''
        Limit topic associations to 2
        '''
        print 111, self.cleaned_data  # subtopic field is missing here
        cleaned_data = self.cleaned_data
        topic = cleaned_data.get('topic', None)
        subtopic = cleaned_data.get('subtopic', None)
        paper = cleaned_data.get('paper', None)
        priority = cleaned_data.get('priority', None)
        paper_obj = get_object_or_404(SubmissionImportData, pk=paper)

        if topic:
            topic_count = PaperTopic.objects.\
                    filter(submission_import_data=paper_obj).count()
            if topic_count >= 2:
                raise forms.ValidationError("You can only select up to two sets of topic and subtopic associations.")

        if PaperTopic.objects.filter(submission_import_data=paper_obj,
               priority=priority).exists():
            raise forms.ValidationError("You have already chosen that priority level.")
        if PaperTopic.objects.filter(submission_import_data=paper_obj,
               topic=topic, sub_topic=subtopic).exists():
            raise forms.ValidationError("You have already chosen that set of Topic and Subtopic association.")
        print 999999000000
        return cleaned_data

当我尝试提交表单时,出现以下错误: &lt;span class="help-inline"&gt;Select a valid choice. 29 is not one of the available choices.&lt;/span&gt;.

我正在根据主题中选择的值通过 AJAX 动态生成子主题下拉列表的选项。

我可以在我的request.POST 中看到subtopic,但是当它到达clean 方法时,subtopic 字段消失了。

我不太清楚发生了什么..

更新

另外,当没有子主题的值时,select 元素被设置为disabled=disabled。当我尝试像这样提交表单时,我可以在我的 clean 方法中获得 subtopic 字段。而当该字段未被禁用时,我无法以我的干净方法获得它。这就像我所期待的相反行为..

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    ChoiceField() 需要一个选项列表来验证。虽然你这样做 这是topic

    self.fields['topic'].queryset = Topic.objects.\
                    filter(setting=event.setting)
    

    subtopic 被初始化为一个空列表,因此没有任何选项是有效的。

    您必须使用每个可能的子主题实例初始化 self.fields['subtopic'].choices,并使用 Javascript 决定将显示/隐藏哪些子主题(取决于选择的主题)。

    【讨论】:

      猜你喜欢
      • 2018-04-30
      • 2018-08-13
      • 2016-05-18
      • 1970-01-01
      • 2012-01-22
      • 2020-10-30
      • 2016-09-30
      • 2018-06-11
      • 2021-04-12
      相关资源
      最近更新 更多