【问题标题】:Django: loosing form attribute when changing <select> options in form templateDjango:更改表单模板中的 <select> 选项时丢失表单属性
【发布时间】:2017-11-14 15:36:54
【问题描述】:

在我的 Django 应用程序中,一个模板可以手动显示来自模型的表单字段。在这个模板中,我有几个字段,选项在我的forms.py 中设置。其中一个选项是元组('new','New...'),当它被选中时,会出现一个弹出窗口(引导模式),用户可以添加一个选项,该选项被添加到select 的选项中。

但是当提交表单时,我有一个错误,因为缺少该字段的表单键:KeyError: 'country',如果我打印表单,则缺少国家/地区键:

{'genotype': '?', 'complete_genome': False, 'seq_tech': '?', 'isolation_source': 'te', 'mol_type': '?', 'NT_seq': 'TTG', 'source': '?', 'host': 'chicken', 'species': 'A', 'isolate': 'te1', 'sourceLink': '', 'subtyping_ref': '?', 'PK_idSequence': 'test', 'strain': 'te1_strain', 'comment': '', 'subtype': '?'}

我的forms.py

UNKNOWN_START_LIST = [('?','?')]
NEW_END_LIST = [('new','New...')]

class SequenceForm(ModelForm):

    # create the form fields
    PK_idSequence = CharField(max_length=15, label='Sequence ID')

    # get the existing country values in the database
    tmpCountries = sorted(list(set([seq.country for seq in Sequence.objects.all() if seq.country is not None and seq.country != '?'])))
    countryChoices = UNKNOWN_START_LIST + [(tmpCountry, tmpCountry) for tmpCountry in tmpCountries] + NEW_END_LIST

    # the countryChoices will be [('?', '?'), ('France', 'France'), ('Germany', 'Germany'), ('Japan', 'Japan'), ('USA', 'USA'), ('new', 'New...')]
    country = ChoiceField(choices = countryChoices,
                    initial='?', 
                    required = False)

    # ... more stuffs


    class Meta:
        model = Sequence
        fields = ['PK_idSequence', 'genotype', 'subtype', 'host', 'country', 'complete_genome', 'seq_tech', 'NT_seq', 'col_date',
                'isolation_source', 'isolate', 'strain', 'species', 'mol_type', 'subtyping_ref', 'source', 'sourceLink', 'comment']

    # custom clean form for Sequence    
    def clean(self):
        cleaned_data = super(SequenceForm, self).clean()

        # where the error is raised
        if cleaned_data['country'] is not None:
            cleaned_data['country'] = cleaned_data.get('country').title()

我的template.html:

{# The modal window to record a new Country #}
<div id="modal_new_country" class="modal" tabindex="-1" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Record a new country:</h5>
                </div>
                <div class="modal-body">
                    <input type="text" name="new_country_text" id="new_country_text">
                </div>
                <div class="modal-footer">
                    <button id="new_country_button" type="button" class="btn btn-primary">Submit</button>
                    <button id="new_country_cancel_button" type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                </div>
        </div>
    </div>
</div>

<form class="single_upload_form" action="{% url 'upload' dataType method %}" method="post">
    {% csrf_token %}
    <div class="container">
    <div class="row">
        <div class="col">
            <div class="{{form.name.css_classes}}">
                {{form.PK_idSequence.label_tag}}{{ form.PK_idSequence.errors }}</br><span class="form_field">{{ form.PK_idSequence }}</span>
            </div>
        </div>
        <div class="col">
            <div class="{{form.name.css_classes}}">
                {{ form.country.label_tag }}{{ form.country.errors }}</br><span class="form_field">{{ form.country }}</span>
            </div>
        </div>
    <div class="row">
        <div class="col">
            <input type="submit" value="Submit"/>
        </div>
    </div>
</form>

我的jQuery.js:

jQuery(document).ready(function() {
/* ############### Country dropdown select ############### */

    // in upload form if Country dropdown is set to New... create a modal to get the new country
    $("#id_country").change(function(){
        var selectedValue = $(this).find("option:selected").attr("value");
        switch (selectedValue){
            case "new":
                $('#modal_new_country').modal('show');
                break;
        }
    }); 

    // Add the new Country to the select options
    $("#new_country_button").click(function() {
        var newCountry = $("#new_country_text").val();
        newCountry = newCountry.substr(0,1).toUpperCase() + newCountry.substr(1);
        $('#id_country').append('<option value="'+newCountry+'" selected="selected">'+newCountry+'</option>');
        $('#modal_new_country').modal('hide');
    });

    // cancel button for modal Country set selected option to '?'
    $("#new_country_cancel_button").click(function() {
        $('#id_country').val('?');
        $('#modal_new_country').modal('hide');
    });

})

我猜问题出在select id_country 中的新值不是来自form 的初始选项的一部分,我该如何解决这个问题?

【问题讨论】:

    标签: jquery django forms


    【解决方案1】:

    如果有帮助,我找到了一种将新的&lt;option&gt; 添加到&lt;select&gt; #id_country 的方法。在我的forms.py 中,我将ChoiceField 替换为CharField,该小部件是forms.Select,我在其中放置了countryChoices

    country = ChoiceField(choices = countryChoices, initial='?', required = False)
    

    通过

    country = CharField(max_length=50, widget=forms.Select(choices=countryChoices), required=False)
    

    因此,由于 country 属性是 CharFieldinvalid_choice 不再引发验证错误,form cleaned_data 现在具有键 'country' 的新值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-15
      • 2012-08-10
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多