2012-07-18 5 views
5

Ich habe mit einigen verdächtigen Verhalten der create() Methode User Objekt-Manager aufgetreten. Sieht aus wie password Feld ist nicht erforderlich zum Erstellen User Objekt, wenn Sie diese Methode verwenden. Als Ergebnis erhalten Sie User mit Leerzeichen password. Wenn Sie die Methode create_user verwenden und nicht password angeben, wird User mit einem nicht verwendbaren Kennwort erstellt (bis set_unusable_password()).Benutzer-Manager-Methoden create() und create_user()

bin ich nicht sicher, warum create() Methode nicht raise exception tut, wenn Sie versuchen, password ohne Benutzer zu erstellen - in der Dokumentation es angegeben, dass dieses Feld erforderlich ist. Ist etwas falsch in create() Methode/Dokumentation?

Antwort

9

das genau ist, warum das Benutzermodell für die Erstellung von Benutzern einen benutzerdefinierten Manager mit einer UserManager.create_user() Methode hat. Es gibt zwei Probleme mit der Verwendung der QuerySet.create() Methode auf User Instanzen:

  1. Wenn Sie das Management Befehl python manage.py sql ausführen, achten Sie auf die auth_user Schema:

    CREATE TABLE "auth_user" (
        ... 
        "password" varchar(128) NOT NULL, 
        ... 
    ) 
    

    In SQL, eine leere Zeichenfolge, '' , entspricht nicht NULL, dh ISNULL('') != TRUE.

  2. QuerySet.create() und QuerySet.update()lösen keine Modellvalidierung. Die Modellüberprüfung findet nur statt, wenn ModelForm Instanzen die Instanzmethode Model.full_clean() aufrufen.

    Das Erhöhen eines Validierungsfehlers im Zusammenhang mit der Verwendung der API QuerySet direkt macht in Django keinen Sinn. Deshalb können Sie etwas wie User.objects.create(username='foo', password='') tun, obwohl CharField().validate(value='', None) eine ValidationError für eine leere Zeichenfolge auslösen würde.

Aus den genannten Gründen sollten Sie verwenden User.objects.create() verschieben und sich auf der mitgelieferten User.objects.create_user() Methode aus dem benutzerdefinierten Manager des Modells.

+0

schöne erweiterte Antwort :-) –

0

Blick auf Djangos Quelle User-Modell, gibt es einen benutzerdefinierten Manager-Snippet:

class UserManager(models.Manager): 
    # ... 
    def create_user(self, username, email=None, password=None): 
     """ 
     Creates and saves a User with the given username, email and password. 
     """ 
     now = timezone.now() 
     if not username: 
      raise ValueError('The given username must be set') 
     email = UserManager.normalize_email(email) 
     user = self.model(username=username, email=email, 
          is_staff=False, is_active=True, is_superuser=False, 
          last_login=now, date_joined=now) 

     user.set_password(password) 
     user.save(using=self._db) 
     return user 
+1

Ich verstehe, dass das Passwort für create_user nicht erforderlich ist. Es wurde implementiert, wenn Sie sich gegen eine externe Quelle authentifizieren. Ich denke nur, dass es nicht angemessen ist, Verhalten für User Manager create() -Methode. – sunprophit

+1

Nein, weil der Benutzer einen benutzerdefinierten Manager definiert hat, aber die gleiche Variable 'objects' verwendet erstellt –

Verwandte Themen