2009-10-12 32 views
8

Soy bastante nuevo en Django y estoy usando Django 1.0. tengo esto:
forms.py:Formulario Django con solo un campo Boolean

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... 

El problema es que la forma no es válida a menos que se marca la casilla, por lo que no parece ser una forma de obtener un valor falso del campo. Por lo que puedo entender desde the docs, debería funcionar. Funciona si agrego un CharField a mi formulario ...

¿Estoy entendiendo mal algo aquí o es esto un error? (Sí, he buscado en Google pero no encontró nada relevante)

Actualización: Como sugiere @Dominic Rodger, He intentado añadir un campo oculto
dummy = forms.CharField(initial='dummy', widget=forms.widgets.HiddenInput())
y eso hace que la forma válida. Esta solución me permite seguir adelante ahora, pero aún sería interesante saber si estoy entendiendo mal algo ...

+0

Huh. Me parece un error. ¿Podría solucionarlo utilizando un campo oculto? –

+0

Ha habido algunos informes de errores que suenan algo similares: consulte http://www.google.co.uk/search?q=django+checkbox+forms+bug –

+0

Lo intentaré. Sospecho que al formulario no le gustan los datos vacíos, ya que el navegador no incluirá el campo para una casilla de verificación sin marcar. – Niklas

Respuesta

8

Hubo un error en el código en mi pregunta. Gracias a @ d0ugal por ayudarme a detectarlo al incluir un ejemplo ligeramente diferente.El problema era aquí:

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

El error fue que supuse que sería request.POST resultado verdadero si fuera un poste. Pero como los navegadores no publican nada para una casilla de verificación no marcada, y ese era el único campo, los datos POST eran un diccionario vacío, que se evalúa como Falso. Esto provocó que None se utilizara como datos de inicialización, haciendo que el formulario se desatara y no fuera válido.
El ejemplo de @ d0ugal hace lo más seguro y prueba primero la solicitud.método.

4

Esto también funciona para mí en 1.1, 1.0.3 y 1.0 (tengo estos tres virtuales configuración de ambientes). Solo probé esto en Firefox así que si es un problema con el navegador eso es otra cuestión, pero hasta donde yo sé, todos manejan los datos POST con casillas de verificación de la misma manera.

Aquí está el código completo del proyecto para que pueda reproducirlo en su tiempo libre y compararlo con el suyo para ver la diferencia.

Configuración en Ubuntu

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

A continuación, en la carpeta de aplicación 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 de django formas de importación

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 importar *

from myfirst.views import testing 

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

A continuación, sólo ejecutar el proyecto $ python manage.py runserver y vaya a http://localhost:8000/. En realidad, encontrará que lo requerido no hace nada con la casilla de verificación, ya que no puede dejarla en blanco: una respuesta 'en blanco' es efectivamente 'no'. Si quiere asegurarse de que un usuario seleccione una respuesta, tenga una opción múltiple donde el usuario tenga que seleccionar sí o no. También podría obligarlos a responder con botones de radio.

+0

En realidad, el valor predeterminado para 'required' es True, vea http://docs.djangoproject.com/en/dev/ref/forms/fields/#required. Pero tu respuesta me hizo detectar mi error, ¡así que +1 para eso! Responderé a mi propia pregunta para dejar en claro a los futuros lectores cuál fue el problema ... – Niklas

+0

Nunca dije que el valor predeterminado requerido era Verdadero o Falso :) Simplemente dije que no es diferente ya que es imposible dejarlo una casilla de verificación 'en blanco' está seleccionada o no seleccionada. Por lo tanto, siempre hay un valor: ser requerido o no hacer la diferencia. –

Cuestiones relacionadas