2012-08-03 13 views
6

No encuentro ninguna respuesta relevante sobre este tema. Me gustaría crear validadores en Django con algunos parámetros como:¿Es posible tener validadores con parámetros?

en un archivo forms.py:

class DateForm(forms.Form): 
    forms.DateField(
     validators=[validate_range_of_date(value,"01/06/2012","31/03/2013")] 
     ) 

En un archivo validators.py:

def validate_range_of_date(date_to_verify, min_date, max_date): 
    ... 

que ahora puedo hágalo a través del método de limpieza o haciendo un campo personalizado, pero creo que sería mejor hacerlo a través de un validador. ¿Es posible?

Gracias de antemano

Respuesta

6

Puede intentar escribir una función que devuelva una función.

def date_range_validator(min_date, max_date): 
    def innerfn(date_to_test): 
     if not (min_date <= date_to_test <= max_date): 
      raise ValidationError(
       'Inappropriate date: %s is not between %s and %s' % 
       (date_to_test, min_date, max_date) 
       ) 
    return innerfn 

A continuación, podría crear el validador que realmente desea llamando esta función:

class DateForm(forms.Form): 
    forms.DateField(
     validators=[ 
      date_range_validator(
       datetime.date(2012, 06, 01), datetime.date(2013, 03, 31) 
       ) 
      ] 
     ) 

(gracias por la corrección @user2577922)

PS no he probado esto, pero es de esperar que Obtenga la idea: escriba una función que toma el dos fechas que desea tener como límites de su rango, y que devuelve una función que comprueba que la fecha en que se pasa está dentro del rango.

+2

me trataron respuesta de Duncan (en models.py) y tengo que trabajar usando: aumentar ValidationError ("foo bar") en lugar de retorno ValidationError ("foo bar") – user2577922

0

Puede probar usando una expresión lambda (Nunca probado a mí mismo, así que no sé si funcionará o no):

forms.DateField(validators=[lambda value: validate_range_of_data(value, "01/06/2012", "31/03/2012")]) 

Por supuesto, debes preguntarte si es "más agradable" que solo validar el método de limpieza del campo.

5

Sugiero echar un vistazo a django.core.validators para ver cómo Django usa el validador Regex, y lo extiende para utilizarlo para diferentes tipos de campos.

class MyValidator (object): 
    def __init__(self, params): 
     pass # Init the instance variables here 

    def __call__(self, value): 
     pass # Actual validation logic comes here 

simplemente pasan sus parámetros al validador en

validators=[MyValidator(params)] 

no hemos probado, pero no veo ninguna razón por la que no funcionaría.

EDIT:

tenido la oportunidad de probarlo y funciona.

+0

Echando un vistazo al código Regex es una muy buena idea – serfer2

3

Basado en la solución de amertkara, paso la dirección de correo electrónico del usuario al formulario, luego valido la entrada del usuario desde su propia dirección de correo electrónico.

# form 
class new_user_form(forms.Form): 
    def __init__(self, *args, **kwargs): 
     own_mail = kwargs.pop('own_mail') 
     super(new_user_form, self).__init__(*args, **kwargs) 
     self.fields['email'] = forms.EmailField(
      label='', 
      required=True, 
      validators = [ not_own_mail(own_mail) ] 
     ) 

# validator 
class not_own_mail(object): 
    def __init__(self, email): 
     self.email = email 

    def __call__(self, value): 
     if value == self.email: 
      raise ValidationError('It must be a different email address.') 
     else: 
      return value 
Cuestiones relacionadas