2009-05-27 12 views
15

Sto imparando Django costruendo una semplice app di ricette. Ho un modello di tabella 1 che utilizza l'opzione di campo 'choice' per le categorie di ricette piuttosto che utilizzare una seconda tabella 'categorie' e una relazione di chiave esterna. Così ho creato la tabella db tramite syncdb e poi ho caricato la tabella con i dati di test. Quando vado a Admin e cliccare sul link 'ricette', nel tentativo di visualizzare le ricette ottengo il seguente errore:errore django 'troppi valori da decomprimere'

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 

Se qualcuno può far luce su questo errore criptico che sarebbe grande. Db è Sqlite. La versione di Django è 1.0. Il modello è elencato di seguito:

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

meno, c'è un bug nella versione dev Django, questo non sembra problematico. Qualche possibilità di avere modelli di amministrazione personalizzati o definizioni ModelAdmin da qualche parte? –

risposta

2

Se dovessi tirare a indovinare, è perché tutto ciò che è nel modello amministrativo si aspetta una lista di tuple, ma hai invece fornito una tupla di tuple (da qui il "troppi valori "). Provare a sostituire con una lista, invece:

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

Le scelte di Django possono essere tutte iterabili (http://docs.djangoproject.com/en/dev/ref/models/fields/#choices), non solo una "lista o una tupla", quindi non è probabile, anche se è un buon pensiero. –

+0

Ah, dannazione. Vale un tentativo! –

0

Ho funzionato. La maggior parte degli errori "troppi valori per decomprimere" che ho trovato mentre googling erano tipi di errore di valore. Il mio errore era un tipo di sintassi del modello. Per caricare la mia tabella delle ricette avevo importato un file csv. Stavo pensando che forse c'era un problema nei dati che sqlite consentiva durante l'importazione. Così ho cancellato tutti i dati e aggiunto 2 ricette manualmente tramite il modulo admin di django. L'elenco delle ricette caricate dopo.

grazie.

+0

Devo dire, questa non è una risposta terribilmente soddisfacente. Sarei più interessato a sapere come risolvere il problema (e quindi cosa fosse), non una soluzione alternativa. Dopo tutto, cosa succede se si verifica di nuovo? Ma sono felice che tu sia riuscito a trovare una soluzione che ha funzionato per te. –

+0

Qui ho avuto lo stesso problema: "troppi valori da decomprimere" Ho controllato lo stack delle eccezioni e ho scoperto che il problema si è verificato in un'operazione "split" su un timestamp. Il timestamp era codificato male perché i dati sono stati inseriti direttamente nella shell sqlite. Il messaggio che django ci dà non è un buon indizio sul vero problema, proprio questo. ;) –

0

Ho appena avuto lo stesso problema ... il mio file cvs proviene da ms excel e i campi data hanno ottenuto il formato sbagliato al momento del salvataggio. Modifico il formato in qualcosa del tipo '2010-05-04 13: 05: 46.790454' (excel mi ha dato 5/5/2010 10:05:47) e voilaaaa non più 'troppi valori per decomprimere'

2

Tu dovrebbe utilizzare un ChoiceField anziché SmallIntegerField

16

Modifica: aggiornato alla luce della correzione di kibibu.

ho incontrato quello che credo sia questo stesso errore, producendo il messaggio:

Caught ValueError while rendering: too many values to unpack 

La mia classe forma era la seguente:

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

Nota che il mio choices tipo qui una tupla.Django documentazione ufficiale recita come segue per la 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

Questo problema è stato risolto con la mia osservando la documentazione e l'utilizzo di un elenco di tuple:

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

Si noti che mentre i documenti dichiarano qualsiasi iterable del modulo corretto può essere usato, una tupla di 2-tuple non ha funzionato:

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

Questo ha prodotto lo stesso errore di prima.

Lezione: si verificano errori.

+0

La lista di tuple funziona anche per me. scelte = [('a_val', 'a'), ('b_val', 'b')]. Grazie! –

+5

'item = forms.ChoiceField (choices = (('17815', '17816')))' NON è una tupla di tuple. È una tupla tra parentesi. Devi fare 'item = forms.ChoiceField (choices = (('17815', '17816'),))'. Nota la virgola. Ovviamente, il secondo esempio è il formato corretto e continua a non funzionare. – kibibu

0

Il commento di kibibu alla risposta di Kreychek è corretto. Questo non è un problema di Django ma piuttosto un aspetto interessante di Python. Riassumendo:

In Python, le parentesi tonde vengono utilizzate per entrambi gli ordini di operazioni e tuple. Quindi:

foo = (2+2) 

si tradurrà in foo essere 4, non è una tupla che è il primo e unico elemento è 4: 4

foo = (2+2, 3+3) 

si tradurrà in foo essendo una tupla bidimensionale: (4,6)

a dire Python che si desidera creare una tupla unidimensionale anziché solo denota l'ordine delle operazioni, utilizza una virgola finale:

foo = (2+2,) 

si tradurrà in foo essere una tupla unidimensionale che è il primo e unico elemento è 4: (4,)

Così per lo scenario:

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

darebbe quello che vuoi. Usare una lista è anche un'ottima soluzione (più secondo Pythonic a mio parere), ma spero che questa risposta sia informativa dato che questo può accadere in altri casi.

Ad esempio:

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

può dare un errore se foo è un iterabile, ma:

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

o:

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

sarà correttamente convertire foo in una stringa se è un iterable o no.

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

Problemi correlati