2009-09-16 6 views
2

Je définis un champ ChoiceField basé sur les données d'un modèle. Cependant, je voudrais préfixer mes options avec une option vide pour sélectionner les objets "non". Mais je ne peux pas trouver une bonne façon d'ajouter cela.Ajouter une option "vide" à un champ ChoiceField basé sur les données du modèle

Tous mes tests comme:

field = forms.ChoiceField(choices=[[0, '----------']].extend([[r.id, r.name] for r in Model.objects.all()])) 

me renvoie une erreur "NoneType objet non itérables". La seule façon que j'ai trouvé jusqu'à présent est la suivante:

def append_empty(choices): 
    ret = [[0, '----------']] 
    for c in choices: 
     ret.append(c) 
    return ret 

Et quand je définis mon champ:

forms.ChoiceField(choices=append_empty([[r.id, r.name] for r in 
    Restaurant.objects.all()]), required=False) 

Cependant, je voudrais essayer de garder mon code propre et ne pas avoir ce genre des horreurs. Auriez-vous une idée pour moi? : p Merci d'avance.

Répondre

8

Une réponse facile est de faire:

field = forms.ChoiceField(choices=[[0, '----------']] + [[r.id, r.name] for r in Model.objects.all()]) 

Malheureusement, votre approche est erronée. Même avec votre approche «travail», les choix de champs sont définis lorsque le formulaire est défini, et non lorsqu'il est instancié. Ainsi, si vous ajoutez des éléments à la table Modèle, ils n'apparaîtront pas dans la liste des choix.

Vous pouvez éviter cela en effectuant l'allocation dans la méthode __init__ de votre formulaire.

Cependant, il existe une approche beaucoup plus simple. Plutôt que de jouer avec les choix de champs dynamiquement, vous devriez utiliser le champ qui est spécifiquement conçu pour fournir des choix à partir d'un modèle - ModelChoiceField. Non seulement cela obtient dynamiquement la liste des éléments du modèle à l'instanciation, mais il inclut déjà un choix vide par défaut. Voir the documentation.

+0

Yay! :) Merci. Ça marche trouver maintenant. –

0

Depuis cette question et sa réponse a presque résolu un problème que je viens d'avoir, j'aimerais ajouter quelque chose. Pour moi, l'identifiant devait être vide car le modèle ne reconnaissait pas '0' comme une option valide, mais il acceptait vide (null = True, blank = True). Dans l'initialiseur:

self.fields['option_field'].choices = [ 
    ('', '------')] + [[r.id, r.name] for r in Model.objects.all()] 
Questions connexes