【问题标题】:ChoiceField form is not valid and returns "too many values to unpack"ChoiceField 表单无效并返回“太多值无法解包”
【发布时间】:2014-01-29 07:16:26
【问题描述】:

所以,我有这个表单,我在下拉列表中显示我所有应用程序模型的列表,并期望用户选择一个以显示其字段。下面是我的表单和 models() 方法,它创建了要作为参数传递给我的 ChoiceField 的模型列表。

*forms.py*
class dbForm(forms.Form):
    model_classes_field = forms.ChoiceField(choices=models(), required=True,)

def models():
apps = get_app('Directories')
m_id = 0
for model in get_models(apps):
    m_id += 1
    model_classes.append({
        'model_name': model._meta.verbose_name,
        'model_id': m_id,
        'model_table': model._meta.db_table,
        'model_object': model.objects.all()  
    })
return model_classes

在我的 views.py 中,我尝试处理 POST 数据,但不幸的是,由于某种原因,表单无效,我无法操作任何数据。此外,form.errors 根本不显示任何内容。

*views.py*
def index(request): 
if request.method == 'POST': # If the form has been submitted...
    form = dbForm(request.POST) # A form bound to the POST data
    if form.is_valid(): # All validation rules pass
            model_classes_field = form.cleaned_data['model_classes_field']
            return HttpResponseRedirect('/list/') # Redirect after POST
    else:
            print "form: ", form.errors
else:
    form = dbForm() # An unbound form
    print "form: ", form.errors
    print "not valid form"

return render(request, 'Directories/index.html', {
            'form': form,
    })

此外,在模板中,每当我尝试提交表单时,它都会返回错误消息“太多值无法解包”,并且不会将我重定向到下一个模板 (list.html)。

*index.html*
{% block content%} 
<div id="content" align="center">                
    <h2> Welcome! this is Directories app! </h2> 
    <form action="" method="post">{% csrf_token %}
{{ form.model_classes_field.errors }}
<label for="id_model_classes_field">Choose from one of the existing tables:</label> 
<select id="id_model_classes_field" name="model_classes_field">         
{% for choice in form.fields.model_classes_field.choices %}
        <option name="m_id" value="{{ choice.model_table }}">{{choice.model_id}}: {{choice.model_name}}</option> 
{% endfor %} 
</select> <br /> 
<input type="submit" value="Change" name="_change" />
</form>
</div>
<div id="bottom">

</div>
{% endblock %}

我在此找到的唯一解决方法是使用要重定向的模板(即 action = "list")填充表单操作,而不是使用 return HttpResponseRedirect('/list/') 在视图中执行此操作。但是,我认为这并不能解决问题,因为表单仍然无效,我无法使用form.cleaned_data 处理数据。奇怪的是即使表单无效也会发送帖子数据。

*

编辑:解决方案

我改变了我的 models() 方法:

def models():
    apps = get_app('Directories')
    for model in get_models(apps):
        model_classes.append( (model._meta.verbose_name, model._meta.db_table), )
    return model_classes

所以我按照@Rohan 的指示包含了一个元组,并对我的 index.html 进行了轻微修改:

...
{% for choice in form.fields.model_classes_field.choices %}
        <option name="m_id" value="{{choice.0}}">{{choice.0}}</option> 
{% endfor %} 
...

表单有效,现在可以处理我的数据。

*

【问题讨论】:

    标签: django forms templates choicefield


    【解决方案1】:

    choices 的值应该是包含恰好有 2 个元素的项目的列表/元组。但是您正在创建可能导致问题的字典列表。

    for model in get_models(apps):
        m_id += 1
        model_classes.append({
            'model_name': model._meta.verbose_name,
            'model_id': m_id,
            'model_table': model._meta.db_table,
            'model_object': model.objects.all()  
        })
    

    因此您可能需要更新models() 方法以返回适当的列表/元组。

    【讨论】:

      猜你喜欢
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 2018-07-01
      • 2021-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多