2012-07-18 9 views
5

Napotkałem pewne podejrzane zachowanie metody obiektu create() dla menedżera obiektów . Wygląda na to, że jeśli używasz tej metody, nie jest wymagane utworzenie obiektu password dla utworzenia obiektu . W rezultacie otrzymasz User z pustym numerem password. W przypadku korzystania z metody create_user i nie określania password tworzy ona User z nieużytecznym hasłem (do set_unusable_password()).Metody zarządzania użytkownikami create() i create_user()

Nie jestem pewien, dlaczego metoda create() nie jest raise exception podczas próby utworzenia użytkownika bez password - w dokumentacji określono, że to pole jest wymagane. Czy coś jest nie tak z metodą/dokumentacją create()?

Odpowiedz

9

Właśnie dlatego model użytkownik ma menedżera niestandardowy z UserManager.create_user() metoda tworzenia użytkowników. Istnieją dwa główne problemy z zastosowaniem metody QuerySet.create() na User przypadkach:

  1. Po uruchomieniu polecenia zarządzania python manage.py sql, należy zwrócić uwagę na schemacie auth_user:

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

    w SQL, pustym ciągiem, '' , nie oznacza NULL, tj. ISNULL('') != TRUE.

  2. QuerySet.create() i QuerySet.update()nie wywołują modelu walidacji. Walidacja modelu ma miejsce tylko wtedy, gdy instancje ModelForm wywołują metodę instancji Model.full_clean().

    Podnoszenie błędu sprawdzania poprawności w kontekście pracy z interfejsem API QuerySet bezpośrednio po prostu nie ma sensu w Django. Dlatego możesz zrobić coś takiego, jak User.objects.create(username='foo', password=''), mimo że CharField().validate(value='', None) podniósłby ValidationError dla pustego łańcucha.

Z powyższych względów należy odroczyć do korzystania User.objects.create() i opierają się na dołączonej User.objects.create_user() metody z niestandardowego menedżera modelu.

+0

ładną, rozszerzoną odpowiedź :-) –

0

Spójrz na źródło modelu użytkownika Django, jest to menedżer zwyczaj, 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

Rozumiem, że hasło nie jest wymagane dla create_user. Zostało to zaimplementowane, jeśli uwierzytelnisz się na jakimś zewnętrznym źródle. Uważam, że nie jest to właściwe zachowanie dla metody create() menedżera użytkownika. – sunprophit

+1

Nie, ponieważ użytkownik ma zdefiniowanego niestandardowego menedżera, ale używa tej samej zmiennej "obiekty", stwórz –

Powiązane problemy