2009-05-27 12 views
15

J'apprends Django en construisant une application de recettes simple. J'ai un modèle de table 1 utilisant l'option de champ 'choix' pour les catégories de recettes plutôt que d'utiliser une deuxième table 'catégories' et une relation de clé étrangère. J'ai donc créé la table db via syncdb et ensuite chargé la table avec les données de test. Quand je vais à admin et cliquez sur le lien « recettes » pour tenter de voir les recettes que je reçois l'erreur suivante:erreur django 'trop de valeurs pour décompresser'

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 

Si quelqu'un peut faire la lumière sur cette erreur cryptique qui serait grande. Db est Sqlite. La version de Django est 1.0. Le modèle est ci-dessous:

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

À moins, il y a un bogue dans la version dev Django, cela ne semble pas problématique. Y a-t-il des chances que vous ayez des modèles d'administration personnalisés ou des définitions ModelAdmin quelque part? –

Répondre

2

Si je devais deviner, c'est parce que tout ce qui est dans le modèle d'administration prévoit une liste de tuples, mais vous avez plutôt fourni un tuple de tuples (d'où les « trop de valeurs "). Essayez de remplacer une liste à la place:

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

Les choix de Django peuvent être n'importe quel itérable (http://docs.djangoproject.com/en/dev/ref/models/fields/#choices), pas seulement une "liste ou un tuple", donc ce n'est pas probable, même si c'est une bonne idée. –

+0

Ah, darn. Ça vaut le coup! –

0

Je l'ai fonctionné. La plupart des «trop nombreuses valeurs pour décompresser» les erreurs que j'ai rencontrées lors du googling étaient des types Value Error. Mon erreur était un type de syntaxe de modèle. Pour charger ma table de recettes j'avais importé un fichier csv. Je pensais qu'il y avait peut-être un problème quelque part dans les données que sqlite permettait d'importer. J'ai donc supprimé toutes les données, puis ajouté 2 recettes manuellement via le formulaire d'administration django. La liste des recettes chargées après cela.

merci.

+0

Je dois dire que ce n'est pas une réponse très satisfaisante. Je serais plus intéressé à savoir comment résoudre le problème (et donc ce que c'était), pas une solution de contournement. Après tout, que se passe-t-il si cela se reproduit? Mais je suis content que vous ayez pu trouver une solution qui fonctionne pour vous. –

+0

Ici, j'ai eu le même problème: "trop ​​de valeurs à décompresser" J'ai regardé la pile d'exceptions et j'ai découvert que le problème est survenu lors d'une opération de "split" sur un horodatage. L'horodatage était mal codé car les données étaient insérées directement dans le shell sqlite. Le message que django nous donne n'est pas un bon indice sur le vrai problème, seulement. ;) –

0

J'ai juste eu le même problème ... mon fichier cvs est venu de ms excel et les champs de date ont obtenu le mauvais format au gain de temps. Je change le format à quelque chose comme '2010-05-04 13: 05: 46.790454' (excel m'a donné 5/5/2010 10:05:47) et voilaaaa pas plus 'trop de valeurs à déballer'

2

Vous devrait utiliser un ChoiceField au lieu de SmallIntegerField

16

Éditer: Mis à jour à la lumière de la correction de Kibibu.

J'ai rencontré ce que je crois est la même erreur, produisant le message:

Caught ValueError while rendering: too many values to unpack 

Ma forme de classe est la suivante:

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

Notez que mon type choices ici un tuple.Django documentation officielle se lit comme suit pour le 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

Ce problème a été résolu par mon observation de la documentation et à l'aide d'une liste de tuples:

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

Notez que, bien que les docs indiquent n'importe quel itérable de la forme correcte peut être utilisé, un tuple de 2-tuples n'a pas fonctionné:

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

Cela a produit la même erreur qu'avant.

Leçon: des bugs se produisent.

+0

La liste des tuples fonctionne pour moi aussi. choises = [('a_val', 'a'), ('b_val', 'b')]. Merci! –

+5

'item = forms.ChoiceField (choices = (('17815', '17816')))' n'est pas un nombre de tuples. C'est un tuple entre parenthèses. Vous devez faire 'item = forms.ChoiceField (choices = (('17815', '17816'),))'. Notez la virgule. Bien sûr, votre deuxième exemple est le bon format et ne fonctionne toujours pas. – kibibu

0

Le commentaire de kibibu à la réponse de Kreychek est correct. Ce n'est pas un problème de Django mais plutôt un aspect intéressant de Python. Pour résumer:

En Python, les parenthèses rondes sont utilisées pour l'ordre des opérations et des tuples. Alors:

foo = (2+2) 

se traduira par foo être 4, pas un tuple qui est le premier et seul élément est 4: 4

foo = (2+2, 3+3) 

se traduira par foo étant un tuple à deux dimensions: (4,6)

pour dire Python que vous voulez créer un tuple unidimensionnelle au lieu de simplement dénotant l'ordre des opérations, utilisez une virgule de fin:

foo = (2+2,) 

se traduira par foo étant une dimension tuple qui est premier élément et seulement 4: (4),

Donc, pour votre scénario:

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

donnerait ce que vous voulez. L'utilisation d'une liste est aussi une excellente solution (plus pythonique à mon avis), mais j'espère que cette réponse est informative puisque cela peut arriver dans d'autres cas.

Par exemple:

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

peut donner une erreur si foo est un itératives, mais:

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

ou:

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

va convertir correctement foo à une chaîne si c'est une itérable ou non.

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

Questions connexes