2012-07-18 8 views
5

Ho riscontrato un comportamento sospetto del metodo create() di User object manager. Sembra che il campo password non sia necessario per la creazione dell'oggetto User se si utilizza questo metodo. In questo modo si ottiene User con vuoto password. Se si utilizza il metodo create_user e non si specifica password, viene creato User con password inutilizzabile (tramite set_unusable_password()).Metodi di gestione utenti create() e create_user()

io non sono sicuro perché create() metodo non raise exception quando si tenta di creare utente senza password - nella documentazione è specificato che questo campo è obbligatorio. C'è qualcosa di sbagliato nel metodo create()/documentazione?

risposta

9

Questo è esattamente il motivo per cui il modello utente ha un manager personalizzato con un metodo UserManager.create_user() per la creazione di utenti. Ci sono due problemi con l'utilizzo del metodo QuerySet.create() su User casi:

  1. Se si esegue il comando gestione python manage.py sql, prestare attenzione ai auth_user schema:

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

    In SQL, una stringa vuota, '' , non equivale a NULL, ovvero ISNULL('') != TRUE.

  2. QuerySet.create() e QuerySet.update()non attivano la validazione dei modelli. La convalida del modello avviene solo quando le istanze ModelForm chiamano il metodo di istanza Model.full_clean().

    Sollevare un errore di convalida nel contesto del lavoro con l'API QuerySet non ha alcun senso in Django. Ecco perché puoi fare qualcosa come User.objects.create(username='foo', password='') anche se lo CharField().validate(value='', None) solleverebbe uno ValidationError per una stringa vuota.

Per le ragioni di cui sopra, si dovrebbe rinviare usare User.objects.create() e si basano sul metodo di User.objects.create_user() fornito dal responsabile personalizzato del modello.

+0

:-) –

0

sguardo al modello di origine utente di Django, c'è un manager personalizzato, frammento:

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

Capisco che la password non è richiesta per create_user. È stato implementato se ci si autentica contro qualche fonte esterna. Sto solo pensando che non è un comportamento appropriato per il metodo create() di User's manager. – sunprophit

+1

No, perché l'utente ha un gestore personalizzato definito ma usa la stessa variabile 'oggetti' crea una risposta estesa estesa a –

Problemi correlati