widgets formularios form fields create django django-forms

formularios - El formulario de Django con BooleanField siempre es inválido a menos que esté marcado



formularios django (5)

Tengo una aplicación que usa el siguiente formulario:

class ConfirmForm(forms.Form): account_name = forms.CharField(widget=forms.HiddenInput) up_to_date = forms.BooleanField(initial=True)

Uso el formulario en el siguiente ejemplo de plantilla:

<form class="confirmform" action="/foo/" enctype="multipart/form-data" method="post"> {{ confirm_form.up_to_date }} Check if this data brings the account up to date.<br> {{ confirm_form.account_name }} <input type="submit" name="confirm" value="Confirm" /> </form>

Mi vista usa la siguiente estructura de código básica:

if request.method == ''POST'': #check for ''confirm'' because I actually have multiple forms in this page if ''confirm'' in request.POST: confirm_form = ConfirmForm(request.POST) if confirm_form.is_valid(): #do stuff else: c[''confirm_form''] = confirm_form else: c[''confirm_form''] = ConfirmForm({''account_name'':''provided_value''})

Dos cosas están mal:

1) Aunque tengo Initial = True, la casilla de verificación está desmarcada cuando se carga la página

2) El formulario siempre es inválido a menos que marque la casilla de verificación. Da errores solo para up_to_date: "Este campo es obligatorio".

He leído esta pregunta similar, pero su solución no se aplica a mi proyecto.

Entonces ... ¿qué está pasando?

Editar:

Actualicé el código anterior para ser más fiel a mi código actual.

El problema n. ° 1 fue culpa mía porque anulaba el valor inicial vinculando datos cuando se creaba una instancia del formulario.

Problema n. ° 2 Todavía considero un problema. Usar required=False on up_to_date solucionará el problema, sin embargo, no parece correcto que al usar el widget predeterminado, un BooleanField pueda ser NULL (haga que la verificación de validez falle) o True pero nunca False .


Asegúrese de no sobrescribir el formulario inicial la primera vez que se carga la página.

Originalmente no estaba verificando si realmente había algo en la solicitud. OBTENER. La primera vez que la página carga request.GET es None, y al llamar a SomeForm (request.GET) borrará realmente los valores iniciales.

def some_view(request): form = SomeForm() if request.method == ''GET'': form = SomeForm(request.GET)

Agregar un cheque para asegurarse de que hay algo en request.GET solucionó esto.

def some_view(request): form = SomeForm() if request.method == ''GET'' and request.GET: form = SomeForm(request.GET)


De acuerdo con los documentos oficiales :

Si desea incluir un booleano en su formulario que puede ser True o False (por ejemplo, una casilla de verificación marcada o no), debe recordar ingresar required=False al crear BooleanField.


En las formas de Django, los campos booleanos se deben crear con required=False .

Cuando la casilla de verificación no está marcada, los navegadores no envían el campo en los parámetros POST de las solicitudes. Sin especificar que el campo sea opcional, Django lo tratará como un campo faltante cuando no esté en los parámetros POST.

Imho sería bueno para Django tener este comportamiento por defecto para los campos de formulario booleanos.

(esto ya fue respondido en comentarios de Yuji pero sería útil como respuesta)


Si haces lo sugerido, tu campo up_to_date siempre será False. ¡Y nunca sabrás si eso es porque el usuario lo quiere así o porque el usuario se saltó el campo !

Tengo el mismo problema con una pregunta OPT_IN legalmente requerida. En el momento de la suscripción, necesito que el usuario tome una decisión de conciencia para permitir que mi sistema le envíe correos electrónicos no solicitados (o no). Estoy trabajando con Django-Allauth y una base de datos de usuario personalizada.

Compartiré mi solución a continuación con la esperanza de que pueda adaptarla a su situación. Lo adapté del DOCS .

forms.py:

# ExtraFieldsSignup as per https://.com/a/12308807 class SignupFormExtraFields(forms.Form): CHOICES = ((''1'', ''YES, keep in touch'',), (''2'', ''No'',)) first_name = forms.CharField(max_length=30, label=''Voornaam'') last_name = forms.CharField(max_length=30, label=''Achternaam'') opt_in = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES) def signup(self, request, user): user.first_name = self.cleaned_data[''first_name''] user.last_name = self.cleaned_data[''last_name''] # Now we figure out what the user chose: if self.cleaned_data[''opt_in''] == ''1'': user.opt_in = True else: user.opt_in = False user.save()


initial=True debe mostrar el widget con checked="checked" por lo que no veo el problema allí .. pero la razón por la cual el formulario no es válido es porque todos los campos son obligatorios por defecto a menos que especifique lo contrario.

Field.required¶ De forma predeterminada, cada clase Field asume que el valor es obligatorio, por lo que si pasa un valor vacío, None o Empty String (""), entonces clean () generará una excepción ValidationError:

Si desea que una casilla de verificación o cualquier otro valor sea opcional, debe pasar required=False en el constructor del campo de formulario.

up_to_date = forms.BooleanField(initial=True, required=False) # no longer required..