2009-10-12 5 views
8

Je suis plutôt nouveau à Django et j'utilise Django 1.0. J'ai ceci:
forms.py:Django forme avec juste un BooleanField

class MyForm(forms.Form): 
    extra_cheeze = forms.BooleanField(required=False, 
             initial=False, 
             label='Extra cheeze') 

views.py:

def order_something(request): 
    form = MyForm(request.POST or None) 
    if request.method == 'POST' and form.is_valid(): 
     # do stuff... 

Le problème est que la forme n'est pas valide que si la case est cochée, donc il ne semble pas être un moyen d'obtenir une valeur False sur le terrain. Pour autant que je peux comprendre de the docs, cela devrait fonctionner. Cela fonctionne si j'ajoute un CharField à mon formulaire ...

Ai-je mal compris quelque chose ici ou est-ce un bug? (Oui, je l'ai googlé mais rien trouvé pertinent)

Mise à jour: Comme suggéré par @Dominic Rodger, j'ai essayé d'ajouter un champ caché
dummy = forms.CharField(initial='dummy', widget=forms.widgets.HiddenInput())
et qui fait la forme valide. Cette solution de contournement me permet d'avancer maintenant, mais il serait toujours intéressant de savoir si j'ai mal compris quelque chose ...

+0

Huh. Ça me semble être un bug. Pourriez-vous contourner ce problème en utilisant un champ caché? –

+0

Il y a eu quelques rapports de bogues qui semblent un peu similaires - voir http://www.google.co.uk/search?q=django+checkbox+forms+bug –

+0

Je vais essayer. Je soupçonne que le formulaire n'aime pas les données vides, puisque le navigateur n'inclura pas le champ pour une case non cochée. – Niklas

Répondre

8

Il y avait un bug dans le code dans ma question. Merci à @ d0ugal pour m'avoir aidé à le repérer en incluant un exemple légèrement différent.Le problème était ici:

form = MyForm(request.POST or None) # <- PROBLEM HERE!!!!!!!!!!!!!!!! 
if request.method == 'POST' and form.is_valid(): 
    # do stuff... 

Le bug était que je supposais que request.POST évaluerait à vrai si c'était un message. Mais comme les navigateurs ne publient rien pour une case à cocher non cochée, et que c'était le seul champ, les données POST étaient un dictionnaire vide, ce qui donne False. Cela a entraîné l'utilisation de None en tant que données d'initialisation, ce qui a entraîné l'annulation de la consolidation du formulaire et son non-validité.
L'exemple de @ d0ugal fait la chose sûre et teste d'abord la méthode request.method.

4

Ceci fonctionne également pour moi sur 1.1, 1.0.3 et 1.0 (j'ai ces trois Virtual configuration des environnements). J'ai seulement testé ceci dans FireFox donc si c'est un problème de navigateur c'est autre chose mais pour autant que je sache, ils traitent tous les données POST avec des cases à cocher la même chose.

Voici le code complet pour le projet afin que vous puissiez reproduire à votre guise et comparer avec le vôtre pour voir la différence.

Mise en place dans Ubuntu

$ django-admin.py startproject testing 
$ cd testing/ 
$ python manage.py startapp myfirst 

ensuite dans le dossier de l'application MyFirst;

/myfirst/views.py

from django.shortcuts import render_to_response 

from myfirst.forms import MyForm 

def testing(request): 
    if request.method == 'POST': 
     form = MyForm(request.POST) 
     if form.is_valid(): 
      result = "valid" 
     else: 
      result = "not valid" 
    else: 
     form = MyForm() 
     result = "no post" 

    return render_to_response('test.html', {'form':form, 'result':result,}) 

/myfirst/forms.py des formes d'importation django

class MyForm(forms.Form): 
    extra_cheeze = forms.BooleanField(required=False,initial=False,label='Extra cheeze') 

/myfirst/templates/test.html

<html> 
<head> 
</head> 
<body> 
    <form action="." method="POST"> 
     {{ form }} 
     <input type="submit" value="test"> 
    </form> 
    {{ result }} 
</body> 
</html> 

/urls.py de django.conf.urls.defaults import *

from myfirst.views import testing 

urlpatterns = patterns('', 
    (r'.*', testing), 
) 

Ensuite, lancez simplement le projet $ python manage.py runserver et accédez à http://localhost:8000/. Vous constaterez que cela ne sert à rien avec la case à cocher, car vous ne pouvez pas le laisser vide - une réponse «vide» est effectivement «non». Si vous voulez vous assurer qu'un utilisateur sélectionne une réponse, ayez un choix multiple où l'utilisateur doit sélectionner oui ou non. Vous pourriez les forcer à répondre avec des boutons radio aussi.

+0

En fait, la valeur par défaut pour 'required' est True, voir http://docs.djangoproject.com/en/dev/ref/forms/fields/#required. Mais votre réponse m'a fait repérer mon bug, donc +1 pour ça! Je vais répondre à ma propre question pour expliquer aux futurs lecteurs quel était le problème ... – Niklas

+0

Je n'ai jamais dit que la valeur par défaut était Vrai ou Faux :) Je viens de dire que ça ne fait pas de différence puisque c'est impossible de partir une case à cocher «vide» est sélectionnée ou non sélectionnée. Donc, il y a toujours une valeur - être requis ou non ne fera pas de différence. –

Questions connexes