Django错误:'too many values to unpack'

25
我正在通过建立一个简单的菜谱应用程序来学习Django。我使用“choices”字段选项为菜谱类别创建了一个1个表模型,而不是使用第二个“categories”表和外键关系。因此,我通过syncdb创建了数据库表,然后加载了测试数据。当我尝试查看食谱时,在管理页面上点击“Recipes”链接时,我会收到以下错误消息:
Template error

In template /var/lib/python-support/python2.6/django/contrib/admin/templates/admin/change_list.html, error at line 34
Caught an exception while rendering: too many values to unpack

如果有人能够解释这个神秘的错误,那就太好了。数据库是SQLite。Django版本是1.0。模型如下:

from django.db import models

class Recipe(models.Model):
    CATEGORY_CHOICES = (
        (1, u'Appetizer'),
        (2, u'Bread'),
        (3, u'Dessert'),
        (4, u'Drinks'),
        (5, u'Main Course'),
        (6, u'Salad'),
        (7, u'Side Dish'),
        (8, u'Soup'),
        (9, u'Sauce/Marinade'),
        (10, u'Other'),        
    )
    name = models.CharField(max_length=255)
    submitter = models.CharField(max_length=40)
    date = models.DateTimeField()
    category = models.SmallIntegerField(choices=CATEGORY_CHOICES)
    ingredients = models.TextField()
    directions = models.TextField()
    comments = models.TextField(null=True, blank=True)

除非Django开发版本中存在错误,否则这看起来不会有问题。你有自定义的管理模板或ModelAdmin定义吗? - Jarret Hardie
8个回答

22

编辑:根据kibibu的更正进行了更新。

我遇到了我认为是同样的错误,产生了以下消息:

Caught ValueError while rendering: too many values to unpack

我的表单类如下:

class CalcForm(forms.Form):
    item = forms.ChoiceField(choices=(('17815', '17816')))
请注意,这里的choices类型是元组。 Django官方文档中对于choices参数的解释如下:

一个可迭代对象(例如列表或元组),其中包含要用作此字段选择项的2元组。此参数接受与模型字段的choices参数相同的格式。

来源:https://docs.djangoproject.com/en/1.3/ref/forms/fields/#django.forms.ChoiceField.choices

我通过阅读文档并使用元组列表来解决了这个问题:

class CalcForm(forms.Form):
    item = forms.ChoiceField(choices=[('17815', '17816')])

需要注意的是,虽然文档说明可以使用任何符合正确格式的可迭代对象,但是一个由2个元组组成的元组并不能起作用:

item = forms.ChoiceField(choices=(('17815', '17816'), ('123', '456')))

这产生了与之前相同的错误。

教训:出现错误是很正常的。


列表的元组对我也适用。选择项=[('a_val','a'),('b_val','b')]。谢谢! - Artyom Chernetsov
9
item = forms.ChoiceField(choices=(('17815', '17816'))) 不是一个元组的元组。它是带括号的元组。你需要写成item = forms.ChoiceField(choices=(('17815', '17816'),))。注意这里有个逗号。当然,你的第二个例子是正确的格式,但仍然无法正常工作。 - kibibu

2
您应该使用ChoiceField而不是SmallIntegerField

1
如果我猜的话,可能是因为管理模板中的内容需要一个元组列表,但你提供了一个元组的元组(因此出现了“太多值”的错误)。尝试用列表替换它:
CATEGORY_CHOICES = [    # Note square brackets.
    (1, u'Appetizer'),
    (2, u'Bread'),
    (3, u'Dessert'),
    (4, u'Drinks'),
    (5, u'Main Course'),
    (6, u'Salad'),
    (7, u'Side Dish'),
    (8, u'Soup'),
    (9, u'Sauce/Marinade'),
    (10, u'Other'),        
]

Django的选择可以是任何可迭代对象(http://docs.djangoproject.com/en/dev/ref/models/fields/#choices),不仅仅是“列表或元组”,因此这不太可能是原因,尽管这是个好想法。 - Jarret Hardie

1

0
kibibu对Kreychek的回答的评论是正确的。这不是Django的问题,而是Python的一个有趣方面。总结一下:
在Python中,圆括号既用于运算顺序,也用于元组。所以:
foo = (2+2)

这将导致foo为4,而不是一个元组,其第一个且唯一的元素为4:4

foo = (2+2, 3+3)

这将导致foo成为一个二维元组:(4,6)

如果要告诉Python你想创建一个一维元组而不仅仅是表示操作顺序,请使用尾随逗号:

foo = (2+2,)

将导致foo成为一个一维元组,其第一个且唯一的元素为4:(4,)

因此,针对您的情况:

class CalcForm(forms.Form):
    item = forms.ChoiceField(choices=(('17815', '17816'),))

会给你想要的结果。使用列表也是一个很好的解决方案(在我看来更符合Python风格),但希望这个答案能提供有用的信息,因为这种情况可能会在其他情况下出现。

例如:

print("foo: %s" % (foo))

如果foo是可迭代的,则可能会出现错误,但是:

print("foo: %s" % (foo,))

或者:

print("foo: %s" % [foo])

无论foo是否可迭代,都会将其正确转换为字符串。

文档:http://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences


关于更符合Python风格,实际上并没有。元组是不可变的,创建后无法更改。通常选择列表应该保持不变,这就是为什么建议使用元组的原因。 - Bobort
1
更Pythonic,指的是更易读。forms.ChoiceField(choices=(('17815', '17816'),)) 有很多括号,可能会让人困惑哪些是元组,哪些是函数调用。如果使用列表而不是元组,就更明显了:forms.ChoiceField(choices=[('17815', '17816')])。你对元组和列表之间的区别是正确的,但我认为我们可以相信 Django 不会在这里更改列表。事实上,它的文档明确表示允许任何可迭代对象,并展示了一个列表的示例:https://docs.djangoproject.com/en/dev/ref/models/fields/#choices - Cameron Lee

0

我刚遇到了同样的问题...我的cvs文件来自于ms excel,保存时日期字段格式出错。我将格式更改为类似于“2010-05-04 13:05:46.790454”(excel给出的是5/5/2010 10:05:47),然后就没有出现“too many values to unpack”的错误了。


0

这个错误在我看来是由于一个函数返回了三个值,而你只将其赋值给了两个。例如:

def test():
    a=0
    b=0
    c=0
.... 
a,b=test() <---three values returned, but only assigning to 2.

a,b,c=test() <---返回三个值,分别赋值给a、b、c。OK


0

我解决了它。在Google搜索时,我遇到的大部分“值过多以拆分”错误都是Value Error类型。我的错误是模板语法类型。为了加载我的食谱表,我导入了一个csv文件。我想可能是在导入时sqlite允许的数据中存在问题。所以我删除了所有数据,然后通过django管理表单手动添加了2个食谱。之后加载了食谱列表。

谢谢。


我必须说,这并不是一个令人满意的答案。我更想知道如何解决问题(以及问题是什么),而不是一个权宜之计。毕竟,如果再次发生该怎么办?但我很高兴你能找到适合自己的解决方案。 - John Feminella
这里我遇到了同样的问题:“too many values to unpack”。我查看了异常堆栈并发现问题出现在时间戳的“split”操作上。由于数据直接插入sqlite shell中,时间戳被错误编码。Django给我们的信息并不是真正问题的好线索,仅此而已。;) - Jayme Tosi Neto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接