Skip to main content
 首页 » 编程设计

python之Django Form Error : Select a valid choice. 29 不是可用选项之一

2025年05月04日22artech

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

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

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

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

我不太确定发生了什么......

更新

另一件事,当子主题没有值时,select元素设置为 disabled=disabled .当我尝试像这样提交我的表格时,我能够得到 subtopic在我的干净方法中的字段。而当该字段未被禁用时,我无法以干净的方法获取它。这就像我期望的相反的行为..

请您参考如下方法:

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

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

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

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