2010-12-19 10 views
11

Estoy usando formularios de Django. Estoy validando en la capa del modelo:¿Cómo puedo generar un ValidationError (o hacer algo similar) en views.py de mi Django?

def clean_title(self): 
    title = self.cleaned_data['title'] 
    if len(title) < 5: 
     raise forms.ValidationError("Headline must be more than 5 characters.") 
    return title 

Sin embargo, hay algunas cosas que necesito para validar en el views.py. Por ejemplo ... ¿fue la última vez que el usuario publicó algo hace más de un minuto?

Ese tipo de cosas requiere request.user, que la capa de modelos no puede obtener. Entonces, debo validar en el views.py ¿Cómo hago algo en views.py para hacer exactamente esto?

raise forms.ValidationError("Headline must be more than 5 characters.") 
+1

Eso no se parece a la validación en la capa del modelo (como en el modelo django.db.models.Model. ¿Te refieres a la capa django.forms.Form/ModelForm? Supongo que –

+0

Tengo un requisito similar por una razón diferente: hay un campo que a veces solo es necesario, dependiendo de la página, por lo que la vista debe imponerlo ya que está estrechamente vinculado a la página. –

Respuesta

12

Creo que la respuesta de gruszczy es buena, pero si buscas una validación genérica que involucre variables que crees que solo están disponibles en la vista, aquí hay una alternativa: pasa los vars como argumentos al formulario y trata con ellos en el método principal clean() de la forma.

La diferencia/ventaja aquí es que su vista se mantiene más simple y todo lo relacionado con el contenido del formulario es aceptable.

por ejemplo:

# IN YOUR VIEW 
# pass request.user as a keyword argument to the form 
myform = MyForm(user=request.user) 


# IN YOUR forms.py 
# at the top: 

from myapp.foo.bar import ok_to_post # some abstracted utility you write to rate-limit posting 

# and in your particular Form definition 

class MyForm(forms.Form) 

    ... your fields here ... 

    def __init__(self, *args, **kwargs): 
     self.user = kwargs.pop('user') # cache the user object you pass in 
     super(MyForm, self).__init__(*args, **kwargs) # and carry on to init the form 


    def clean(self): 
     # test the rate limit by passing in the cached user object 

     if not ok_to_post(self.user): # use your throttling utility here 
      raise forms.ValidationError("You cannot post more than once every x minutes") 

     return self.cleaned_data # never forget this! ;o) 

Nota que el aumento de un genérico ValidationError en el método clean() pondrá el error en myform.non_field_errors por lo que tendrá que asegurarse de que su plantilla contiene {{form.non_field_errors}} si usted está mostrando su formulario manualmente

+0

Gran solución. ¿Es esto un truco? Aunque me encanta, ty – TIMEX

+0

No, no lo llamaría un truco. Simplemente está aprovechando las clases de Formulario Django más que el enfoque predeterminado/tutorial. Lo he usado en muchos lugares y (siempre que sepa lo que hará pop(), ya que elimina el argumento de palabra clave de kwargs, no hay nada que lo atrape. Si no quiere eliminarlo desde kwargs, use get() en su lugar. –

4

Usted no usa ValidationError en las vistas, ya que esas excepciones en cuanto a las formas. Por el contrario, debe redirigir al usuario a alguna otra URL que le explique que no puede volver a publicarla pronto. Esta es la forma correcta de manejar esto. ValidationError se debe generar dentro de una instancia Form, cuando los datos de entrada no se validan. Este no es el caso.

+0

Creo que este es un buen enfoque, pero desde el punto de vista de la usabilidad, sería aún mejor simplemente agregar ese mensaje como un mensaje flash/django.contrib.messages y * no * redirigir a una página nueva, sino solo renderizar la forma completada de nuevo. De esta forma, el usuario puede esperar, digamos, 50 segundos y volver a enviar los datos, sin tener que volver a escribirlo –

Cuestiones relacionadas