1

表单 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字段消失了。

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

更新

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

4

1 回答 1

12

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

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

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

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

于 2012-05-04T10:25:12.587 回答