获取Django表单时出现“值过多无法解包”
我正在尝试从一个表单中获取一些数据,并根据这些数据过滤结果。如果我用一种比较乱的方式(直接从请求中获取数据),是可以工作的,但用Django的正规方式(注释掉的部分)就不行。我总是遇到“解包的值太多”的异常。可能是什么问题呢?
if request.method == 'POST':
print request.POST
entries = entries.filter(date__year=request.POST['year'])
#spanform = SpanForm(request.POST)
#print spanform
#if spanform.is_valid():
# cd = spanform.cleaned_data
# if cd['year']:
# entries = entries.filter(date__year=cd['year'])
这是表单的代码:
class SpanForm(forms.Form):
year = forms.ChoiceField(label="")
def __init__(self, years, *args, **kwargs):
super(SpanForm, self ).__init__(*args, **kwargs)
if years:
self.fields['year'].choices = years
所以,当我测试以下这段代码时:
if request.method == 'POST':
#print request.POST
#entries = entries.filter(date__year=request.POST['year'])
spanform = SpanForm(request.POST)
if spanform.is_valid():
cd = spanform.cleaned_data
if cd['year']:
entries = entries.filter(date__year=cd['year'])
我得到了以下的错误信息:
Environment:
Request Method: POST
Request URL: http://localhost:5000/entries/
Django Version: 1.6.2
Python Version: 2.7.5
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'core')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Template error:
In template /Users/wswld/Code/calc/core/templates/entries.html, error at line 9
too many values to unpack
1 : {% extends "dashboard.html" %}
2 : {% load staticfiles %}
3 :
4 : {% block tab %}
5 :
6 : <form action="." method="post">
7 : {% csrf_token %}
8 : <table>
9 : {{form.as_p}}
10 : </table>
11 : <input type="submit" value="Apply" />
12 : </form>
13 :
14 : <table>
15 : {% for entry in data %}
16 : <tr>
17 : <td>
18 : <a href="./{{ entry.uuid }}/">
19 : <img src="{% static "permalink.png" %}" height="15" width="15"></img>
Traceback:
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/core/handlers/base.py" in get_response
114. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "/Users/wswld/Code/calc/core/views.py" in dashboard
82. return render(request, '%s.html' % tab, {'tab': tab, 'data': data, 'form': spanform})
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/shortcuts/__init__.py" in render
53. return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/loader.py" in render_to_string
169. return t.render(context_instance)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
140. return self._render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in _render
134. return self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render_node
78. return node.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/loader_tags.py" in render
123. return compiled_parent._render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in _render
134. return self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render_node
78. return node.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/loader_tags.py" in render
123. return compiled_parent._render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in _render
134. return self.nodelist.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render_node
78. return node.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/loader_tags.py" in render
62. result = block.nodelist.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render_node
78. return node.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/loader_tags.py" in render
62. result = block.nodelist.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in render
840. bit = self.render_node(node, context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render_node
78. return node.render(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/debug.py" in render
88. output = self.filter_expression.resolve(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in resolve
585. obj = self.var.resolve(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in resolve
735. value = self._resolve_lookup(context)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/template/base.py" in _resolve_lookup
789. current = current()
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/forms.py" in as_p
241. errors_on_separate_row = True)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/forms.py" in _html_output
186. 'field': six.text_type(bf),
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/forms.py" in __str__
425. return self.as_widget()
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/forms.py" in as_widget
475. return widget.render(name, self.value(), attrs=attrs)
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/widgets.py" in render
504. options = self.render_options(choices, [value])
File "/Library/Python/2.7/site-packages/Django-1.6.2-py2.7.egg/django/forms/widgets.py" in render_options
528. for option_value, option_label in chain(self.choices, choices):
Exception Type: ValueError at /entries/
Exception Value: too many values to unpack
2 个回答
1
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或者库的时候。这些问题可能会让我们感到困惑,不知道该怎么解决。比如,有人可能在使用某个函数时,发现它的表现和预期不一样,这时候就需要去查找原因。
通常,我们可以通过查看文档、搜索网上的资料或者在社区里提问来找到解决方案。很多时候,其他人也遇到过类似的问题,他们的经验和解决方法可以帮助我们更快地找到答案。
总之,遇到问题时不要着急,先冷静下来,尝试去理解问题的本质,再寻找解决办法。这样才能更有效地学习和进步。
class SpanForm(forms.Form):
year = forms.ChoiceField(label="")
def __init__(self, years, *args, **kwargs): # here you have 'years' parameter.
super(SpanForm, self ).__init__(*args, **kwargs)
if years:
self.fields['year'].choices = years
if request.method == 'POST':
spanform = SpanForm(request.POST) # where is your 'years' parameter? Now you have request.POST in 'years' variable from __init__ from SpanForm class.
if spanform.is_valid():
cd = spanform.cleaned_data
if cd['year']:
entries = entries.filter(date__year=cd['year'])
4
问题在于你没有在视图中的后置条件里传递年份这个参数。你现在是把请求中的POST字典里的年份参数传过去。你可以选择从表单中的kwargs
里取出年份参数,或者在视图里传递None
。
class SpanForm(forms.Form):
year = forms.ChoiceField(label="")
def __init__(self, *args, **kwargs):
years = kwargs.pop('years', None)
super(SpanForm, self ).__init__(*args, **kwargs)
if years:
self.fields['year'].choices = years
或者
if request.method == 'POST':
spanform = SpanForm(None, request.POST)
if spanform.is_valid():
cd = spanform.cleaned_data
if cd['year']:
entries = entries.filter(date__year=cd['year'])