问题
I'm learning Django by building a simple recipes app. I have a 1 table model using the 'choices' field option for recipe categories rather than using a 2nd 'categories' table and a foreign key relationship. So i created db table via syncdb and then loaded table with test data. When i go to admin and click on the 'Recipes' link in an attempt to view recipes i get the following error:
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
If anyone can shed light on this cryptic error that would be great. Db is Sqlite. Django version is 1.0. The model is listed below:
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)
回答1:
Edit: Updated in light of kibibu's correction.
I have encountered what I believe is this same error, producing the message:
Caught ValueError while rendering: too many values to unpack
My form class was as follows:
class CalcForm(forms.Form):
item = forms.ChoiceField(choices=(('17815', '17816')))
Note that my choices
type here a tuple. Django official documentation reads as follows for the choices
arg:
An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field. This argument accepts the same formats as the choices argument to a model field.
src: https://docs.djangoproject.com/en/1.3/ref/forms/fields/#django.forms.ChoiceField.choices
This problem was solved by my observing the documentation and using a list of tuples:
class CalcForm(forms.Form):
item = forms.ChoiceField(choices=[('17815', '17816')])
Do note that while the docs state any iterable of the correct form can be used, a tuple of 2-tuples did not work:
item = forms.ChoiceField(choices=(('17815', '17816'), ('123', '456')))
This produced the same error as before.
Lesson: bugs happen.
回答2:
You should use a ChoiceField
instead of SmallIntegerField
回答3:
If I had to guess, it's because whatever is in the administrative template expects a list of tuples, but you've instead supplied a tuple of tuples (hence the "too many values"). Try replacing with a list instead:
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'),
]
回答4:
Per http://code.djangoproject.com/ticket/972 , you need to move the assignment CATEGORY_CHOICES = ...
outside the class
statement.
回答5:
I got it working. Most of the 'too many values to unpack' errors that i came across while googling were Value Error types. My error was a Template Syntax type. To load my recipe table i had imported a csv file. I was thinking maybe there was a problem somewhere in the data that sqlite allowed on import. So i deleted all data and then added 2 recipes manually via django admin form. The list of recipes loaded after that.
thanks.
回答6:
I just had the same problem... my cvs file came from ms excel and the date fields gotten the wrong format at saving time. I change the format to something like '2010-05-04 13:05:46.790454' (excel gave me 5/5/2010 10:05:47) and voilaaaa no more 'too many values to unpack’
回答7:
kibibu's comment to Kreychek's answer is correct. This isn't a Django issue but rather an interesting aspect of Python. To summarize:
In Python, round parentheses are used for both order of operations and tuples. So:
foo = (2+2)
will result in foo being 4, not a tuple who's first and only element is 4: 4
foo = (2+2, 3+3)
will result in foo being a two-dimensional tuple: (4,6)
To tell Python that you want to create a one-dimensional tuple instead of just denoting the order of operations, use a trailing comma:
foo = (2+2,)
will result in foo being a one-dimensional tuple who's first and only element is 4: (4,)
So for your scenario:
class CalcForm(forms.Form):
item = forms.ChoiceField(choices=(('17815', '17816'),))
would give what you want. Using a list is a great solution too (more Pythonic in my opinion), but hopefully this answer is informative since this can come up in other cases.
For example:
print("foo: %s" % (foo))
may give an error if foo is an iterable, but:
print("foo: %s" % (foo,))
or:
print("foo: %s" % [foo])
will properly convert foo to a string whether it's an iterable or not.
Documentation: http://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences
回答8:
This error IMO occurs when a function returns three values, and you assign it to 2. e.g.:
def test():
a=0
b=0
c=0
....
a,b=test() <---three values returned, but only assigning to 2.
a,b,c=test() <---three values returned, assigned to 3.OK
来源:https://stackoverflow.com/questions/913590/django-error-too-many-values-to-unpack