Cómo acceder a los datos cuando form.is_valid () es falso

Cuando tengo un formulario Django válido, puedo acceder a los datos con form.cleaned_data. Pero, ¿cómo obtengo los datos que ingresó un usuario cuando el formulario no es válido, es decir, form.is_valid es falso?

Estoy tratando de acceder a los formularios dentro de un conjunto de formularios, por lo que form.data parece solo darme un lío.

Puedes usar

form.data['field_name'] 

De esta manera obtendrá el valor bruto asignado al campo.

Consulte http://docs.djangoproject.com/en/dev/ref/forms/validation/#ref-forms-validation

En segundo lugar, una vez que hayamos decidido que los datos combinados en los dos campos que estamos considerando no son válidos, debemos recordar eliminarlos de los datos_despañados.

De hecho, Django eliminará por completo el diccionario cleaner_data si hay algún error en el formulario. Sin embargo, este comportamiento puede cambiar en el futuro, por lo que no es una mala idea limpiar después de ti mismo en primer lugar.

Los datos originales siempre están disponibles en request.POST .


Un comentario sugiere que el punto es hacer algo que parezca una validación más sofisticada a nivel de campo.

Cada campo recibe los datos no validados, y devuelve los datos válidos o genera una excepción.

En cada campo, se puede realizar cualquier tipo de validación sobre los contenidos originales.

Estaba luchando con un problema similar, y encontré una gran discusión aquí: https://code.djangoproject.com/ticket/10427

No está bien documentado, pero para un formulario en vivo, puede ver el valor de un campo, como lo ven los widgets / usuarios, con lo siguiente:

 form_name['field_name'].value() 

Tengo muchos métodos. Todo lo que puedas recoger.

Supongo que la forma es la siguiente:

 class SignupForm(forms.Form): email = forms.CharField(label='email') password = forms.CharField(label='password', widget=forms.PasswordInput) 

1-1. Obtener de la request

 def signup(req): if req.method == 'POST': email = req.POST.get('email', '') password = req.POST.get('password', '') 

2-1. Obtenga el raw value asignado al campo y devuelva el valor del atributo de data del campo

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) email = sf["email"].data password = sf["password"].data ... 

2-2. Obtenga el valor bruto asignado al campo y devuelva el valor del atributo de value del campo

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) email = sf["email"].value() password = sf["password"].value() ... 

2-3. Obtener el dictionary asignado a los campos.

 def signup(req): if req.method == 'POST': ... sf = SignupForm(req.POST) # print sf.data #  email = sf.data.get("email", '') password = sf.data.get("password", '') ... 

Puedes usar este patrón:

 class MyForm(forms.Form): ... def clean(self): self.saved_data=self.cleaned_data return self.cleaned_data 

En su código:

 if form.is_valid(): form.save() return django.http.HttpResponseRedirect(...) if form.is_bound: form.saved_data['....'] # cleaned_data does not exist any more, but saved_data does. 

Usar form.data no es una buena solución. Razones:

  • Si el formulario tiene un prefijo, las claves del diccionario serán prefijadas con este prefijo.
  • Los datos en form.data no se limpian: solo hay valores de cadena.

Me encontré con un problema similar utilizando un formset. En mi ejemplo, quería que el usuario seleccionara una primera opción antes de una segunda opción, pero si la primera opción tenía otro error, también se mostraba el error “seleccionar primera opción antes de la segunda”.

Para capturar los datos sin limpiar del primer campo, utilicé esto dentro del método de limpieza del campo de formulario:

 dirty_rc1 = self.data[self.prefix + '-reg_choice_1'] 

Entonces, podría probar la presencia de datos en ese campo:

 if not dirty_rc1: raise ValidationError('Make a first choice before second') 

¡Espero que esto ayude!

Puede acceder a los datos desde el método clean () del campo o desde el método clean () del formulario. clean () es la función que determina si la forma es válida o no. Se llama cuando se llama a is_valid (). En el formulario clean (), tiene la lista de datos de cleaned_data cuando puede ejecutar un código personalizado para asegurarse de que todo esté verificado. En el widget, también tiene un clean (), pero usa una sola variable pasada. Para acceder al método clean () del campo, tendrás que subclasificarlo. p.ej:

 class BlankIntField(forms.IntegerField): def clean(self, value): if not value: value = 0 return int(value) 

Si desea un IntField que no se ahogue con un valor vacío, por ejemplo, usaría el anterior.

limpio () en una forma de tipo de obras como esta:

 def clean(self): if self.cleaned_data.get('total',-1) <= 0.0: raise forms.ValidationError("'Total must be positive") return self.cleaned_data 

También puede tener una función clean_FIELD () para cada campo para que pueda validar cada campo individualmente (después de que se llame a clean ())