2009-05-27 3 views
15

Я изучаю Django, создавая простое приложение для рецептов. У меня есть 1 табличная модель, использующая поле «выбор» для категорий рецептов, а не для использования таблицы «2 категории» и отношения внешнего ключа. Поэтому я создал таблицу db через syncdb, а затем загрузил таблицу с тестовыми данными. Когда я иду к администратора и нажмите на ссылку «Рецепты» в попытке просмотреть рецепты я получаю следующее сообщение об ошибке:django 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 

Если кто-то может пролить свет на эту загадочную ошибку, что было бы здорово. Db - 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) 
+0

Если, нет ошибки в Dev версии Django, это не выглядит проблематичным. Есть ли у вас случайные шаблоны админов или определения ModelAdmin? –

ответ

2

Если бы я должен был догадаться, что это потому, что находится в административном шаблоне ожидает список кортежей, но вы вместо поставки кортеж кортежей (отсюда и «слишком много значений «). Попробуйте заменить список вместо:

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'),   
] 
+0

Варианты Django могут быть любыми итерабельными (http://docs.djangoproject.com/en/dev/ref/models/fields/#choices), а не просто «список или кортеж», поэтому это маловероятно, хотя это хорошая мысль. –

+0

Ах, черт. Стоит! –

0

У меня это работает. Большинство «слишкомких значений для распаковки» ошибок, с которыми я столкнулся во время поиска в Интернете, были типами ошибок стоимости. Моя ошибка была типом синтаксиса шаблона. Чтобы загрузить таблицу рецептов, я импортировал файл csv. Я думал, может быть, была проблема где-то в данных, которые sqlite разрешено при импорте. Поэтому я удалил все данные, а затем добавил два рецепта вручную через форму администратора django. Список рецептов, загруженных после этого.

спасибо.

+0

Должен сказать, это не очень приятный ответ. Мне было бы больше интересно узнать, как решить проблему (и, следовательно, что это было), а не обходной путь. В конце концов, что произойдет, если это произойдет снова? Но я рад, что вы нашли решение, которое сработало для вас. –

+0

Здесь у меня была та же проблема: «слишком много значений для распаковки» Я посмотрел на стек исключения и выяснил, что проблема возникла при операции «split» на отметке времени. Временная метка была плохо кодирована, потому что данные были вставлены непосредственно в оболочку sqlite. Сообщение django дает нам не хорошую подсказку о реальной проблеме, просто она. ;) –

0

У меня была такая же проблема ... мой файл cvs пришел из ms excel, а поля даты получили неправильный формат при экономии времени. Я меняю формат на что-то вроде «2010-05-04 13: 05: 46.790454» (excel дал мне 5/5/2010 10:05:47) и voilaaaa больше не «слишком много значений для распаковки»

2

Вы следует использовать ChoiceField вместо SmallIntegerField

16

Редактировать: Обновлено в свете коррекции кибибу.

Я сталкивался, что я считаю, это та же самая ошибка, производя сообщение:

Caught ValueError while rendering: too many values to unpack 

Моя форма класс следующим образом:

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

Обратите внимание, что мой choices типа здесь кортеж.Джанго официальная документация гласит для choices арг:

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.

ЦСИ: 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'))) 

Это привело к той же ошибке, что и раньше.

Урок: ошибки происходят.

+0

Список кортежей работает и для меня. = всячески манипулировать [('a_val', 'а'), ('b_val', 'б')]. Благодаря! –

+5

'item = forms.ChoiceField (choice = (('17815', '17816')))' НЕ является кортежем кортежей. Это кортеж в круглых скобках. Вам нужно сделать 'item = forms.ChoiceField (choice = (('17815', '17816'),))'. Обратите внимание на запятую. Конечно, ваш второй пример - правильный формат и по-прежнему не работает. – kibibu

0

Комментарий kibibu к ответу Крейчека верен. Это не проблема Django, а интересный аспект Python. Подводя итог:

В Python круглые круглые скобки используются как для порядка операций, так и для кортежей. Итак:

foo = (2+2) 

приведет к обув равен 4, а не кортеж, кто первый и единственный элемент 4: 4

foo = (2+2, 3+3) 

приведет к обув быть двумерным кортеж: (4,6)

сказать Python, что вы хотите создать одномерный кортеж, а не просто обозначая порядок операций, используйте запятая:

foo = (2+2,) 

приведет к Foo быть одномерным кортеж, кто первый и единственный элемент 4: (4,)

Так что для вашего сценария:

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

даст то, что вы хотите. Использование списка - отличное решение (более Pythonic, на мой взгляд), но, надеюсь, этот ответ информативен, так как это может возникнуть в других случаях.

Например:

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

Смежные вопросы