2010-07-12 5 views
12

Mache ich etwas falsch, oder ist das ernsthaft was die Entwickler erwarten, dass ich jedes Mal schreibe, wenn ich überprüfen möchte, ob zwei Felder gleich sind?Warum ist es so kompliziert zu überprüfen, ob zwei Passwörter in Django übereinstimmen?

def clean(self): 
    data = self.cleaned_data 
    if "password1" in data and "password2" in data: 
     if data["password1"] != data["password2"]: 
      self._errors["password2"] = self.error_class(['Passwords do not match.']) 
      del data['password2']  
    return data 

Und warum muss ich validieren, dass der Benutzername eindeutig ist?

def clean_username(self): 
    data = self.cleaned_data['username'] 
    if User.objects.filter(username=data).exists(): 
     raise ValidationError('Username already taken.') 
    return data 

Es ist ein ModelForm. Es sollte schon wissen, dass es eine einzigartige Einschränkung gibt?

Antwort

26

Hier ist, was ich tun würde:

Dies ist die einzige saubere Methode ist Sie müssen definieren, um sicherzustellen, dass 2 Passwörter korrekt sind und dass der Benutzername gültig ist.Verwenden Sie die clean_fieldname Methode, damit Sie den Benutzernamen nicht mehr überprüfen müssen.

def clean_password2(self): 
    password1 = self.cleaned_data.get('password1') 
    password2 = self.cleaned_data.get('password2') 

    if not password2: 
     raise forms.ValidationError("You must confirm your password") 
    if password1 != password2: 
     raise forms.ValidationError("Your passwords do not match") 
    return password2 

Sie haben völlig Recht, Sie brauchen nicht den Benutzernamen eindeutig ist zu überprüfen, weil der Modelform weiß es einzigartig sein muss.

Das Problem mit Ihrem Code ist, dass Sie die clean()-Methode überschreiben, was bedeutet, dass das ModelForm seine "echte" clean() nicht tut.

Um die Standardvalidierung zu erhalten, rufen Sie super(MyForm, self).clean() oder besser noch nicht clean überhaupt überschreiben und nur clean_password2 angeben.

+0

Ich denke, das ist der Schluss, zu dem ich schließlich auch gekommen bin, danke. Vergiss diese Frage :) – mpen

+0

Hoppla, ich habe nicht realisiert, dass das so alt war: D –

+0

Immer noch gut, dass du darauf geantwortet hast :) – GreenAsJade

1

Sie könnten auch einen else: Teil für die erste if hinzufügen. Momentan gibt die Funktion data zurück, ohne irgendwelche Fehler zu setzen, selbst wenn eines der Passwörter fehlt - ist das das beabsichtigte Verhalten?

if "password1" in data and "password2" in data: Dies stellt sicher, dass beide Kennwörter vorhanden sind. Ohne diese Zeile erhalten Sie einen Fehler in der nächsten Zeile, in der Sie data[password1] und data[password2] lesen, wenn einer von ihnen nicht vorhanden ist.

Die nächsten drei Zeilen vergleichen die Passwörter und setzen die entsprechende Fehlermeldung - das ist erforderlich, nicht wahr?

Wie sie sagen, machen Sie die Dinge so einfach wie möglich, nicht mehr.

+0

Ich denke nicht * das ist notwendig ... wenn eines der beiden Passwort fehlt, bedeutet das, dass schon ein Fehler aufgetreten ist, oder? Ich muss nicht wirklich einen zweiten werfen. Und ja, das könnte lächerlich einfacher werden. Wie wäre es, wenn ich die Felder definiere, schreibe ich passwort2 = PasswordField (validate = EqualTo ('password1')) '? Es sollte in der Lage sein, den Rest herauszufinden. – mpen

4

Erstens, sind Sie ernsthaft beschweren über vier Zeilen von Boiler-Platte Code? Wenn es Sie wirklich stört, erstellen Sie eine PasswordForm Klasse, die diese saubere Logik enthält und sie für Ihre eigenen Formulare nach Bedarf untergliedert.

Zweitens müssen Sie nicht Unique Constraints manuell validieren. Wie Sie sagen, macht das ModelForm es für Sie.

bearbeiten nach Kommentar

Diese ‚seltsame Syntax‘ ist, weil die Überprüfung, dass zwei Kennwortfelder Spiel ein unterschiedlichen Strömungs sind als das normale Schema der Dinge. Zunächst einmal überprüfen Sie die Hauptmethode clean anstelle der feldspezifischen clean_myfield. Wenn es Letzteres gewesen wäre, erhob man nur eine Ausnahme und Django entfernt tatsächlich die Felddaten.

Also nein, das ist nicht mehr als 7 Zeilen auf jeder Form - meine Notiz Subklassifizieren sehen - und es sicherlich ist nicht 7 Zeilen mal mehr Felder, weil Sie dies nicht für jede andere Art machen wollen von Feld.

+0

Naja, da ist irgendwas kaputt, dann ... weil ich gerade einen doppelten Schlüsselfehler bekommen habe. Ich wollte nur ein bisschen meckern, weil ich dieses Projekt satt habe :( – mpen

+0

Und es ist 7 Zeilen ... von seltsamer Syntax. Warum muss ich überprüfen, ob die Daten im Diktat sind und dann löschen? Isn Das ist ein bisschen ein seltsames Design? Es gibt bereits eine Fehlerliste, es kann überprüfen, ob es wissen will, ob es einen Fehler gab, und ich sollte in der Lage sein, einfach einen anderen anzufügen, ohne es wirklich zu kümmern Und dann, warum Daten zurückgeben? Ich manipuliere bereits selbst. Cleaned_data, es scheint nicht wirklich notwendig, irgendetwas zurückzugeben. Wenn sie mich im Diktat passierten, dann vielleicht. – mpen

+0

Und es ist nicht nur 7 Zeilen .. Es sind 7 Zeilen auf jedem einzelnen verdammten Formular, multipliziert mit mehreren Feldern. – mpen

4

http://k0001.wordpress.com/2007/11/15/dual-password-field-with-django/


Edit: gefunden, wie die Admin-Form behandelt das Problem aus: http://code.djangoproject.com/svn/django/trunk/django/contrib/auth/forms.py

class AdminPasswordChangeForm(forms.Form): 
    """ 
    A form used to change the password of a user in the admin interface. 
    """ 
    password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput) 
    password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput) 

    def __init__(self, user, *args, **kwargs): 
     self.user = user 
     super(AdminPasswordChangeForm, self).__init__(*args, **kwargs) 

    def clean_password2(self): 
     password1 = self.cleaned_data.get('password1') 
     password2 = self.cleaned_data.get('password2') 
     if password1 and password2: 
      if password1 != password2: 
       raise forms.ValidationError(_("The two password fields didn't match.")) 
     return password2 

    def save(self, commit=True): 
     """ 
     Saves the new password. 
     """ 
     self.user.set_password(self.cleaned_data["password1"]) 
     if commit: 
      self.user.save() 
     return self.user 
Verwandte Themen