2012-08-03 15 views
6

Ich kann keine relevante Antwort zu diesem Thema finden. Ich möchte Validatoren in Django erstellen mit einigen Parametern wie:Ist es möglich, Validatoren mit Parametern zu haben?

In einer forms.py Datei:

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

In einer validators.py Datei:

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

ich jetzt kann ich mach es über die clean-Methode oder mache ein benutzerdefiniertes Feld, aber ich denke, es wäre schöner, es über einen Validator zu tun. Ist es möglich?

Vielen Dank im Voraus

Antwort

6

Sie könnten versuchen, eine Funktion zu schreiben, die eine Funktion zurückgibt.

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 

Sie könnten dann den Validator erstellen Sie tatsächlich durch Aufruf dieser Funktion:

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

(danke für die Korrektur @user2577922)

PS ich nicht getestet habe, aber hoffentlich Holen Sie sich die Idee - schreiben Sie eine Funktion, die die zwei Daten, die Sie als die Grenzen Ihres Bereichs haben möchten, und die eine Funktion zurückgibt, die überprüft, ob ein Datum, das es übergeben wird, in dem Bereich ist.

+2

Ich versuchte Duncan Antwort (in models.py) und bekam es mit zu arbeiten: Validation ("foo bar") statt Rückkehr Validation ("foo bar") erhöhen – user2577922

0

Sie mit einem Lambda-Ausdruck können versuchen (es nie versucht, mich, so dass ich weiß nicht, ob es funktionieren wird oder nicht):

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

Natürlich Sie müssen sich fragen, ob das "schöner" ist als nur in der sauberen Methode des Feldes zu validieren.

5

Ich würde vorschlagen, einen Blick auf django.core.validators zu werfen, um zu sehen, wie Django den Regex-Validator verwendet, und erweitert es für verschiedene Arten von Feldern zu verwenden.

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

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

einfach Ihre Parameter an den Validator in

validators=[MyValidator(params)] 

nicht getestet passieren, aber ich sehe keinen Grund, warum es nicht funktionieren würde.

EDIT:

hatte eine Chance, es zu testen und es funktioniert.

+0

einen Blick auf den Code Regex Taking ist eine sehr gute Idee. – serfer2

3

Basierend auf der Lösung von Amertkara übergebe ich die E-Mail-Adresse des Benutzers an das Formular, dann validiere ich die Benutzereingabe über seine eigene E-Mail-Adresse.

# 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 
Verwandte Themen