2012-07-18 47 views
5

我遇到了一些create()方法User對象管理器的可疑行爲。如果使用此方法,看起來像password字段不需要創建User對象。結果你得到User空白password。如果您使用create_user方法並且未指定password,則會創建User且密碼不可用(通過至set_unusable_password())。用戶管理器方法create()和create_user()

我不確定爲什麼create()方法不是raise exception當您嘗試創建沒有password的用戶時 - 在文檔中指定該字段是必需的。 create()方法/文檔有問題嗎?

回答

9

這正是爲什麼用戶模型有一個自定義經理創建用戶UserManager.create_user()方法。有兩個問題與使用QuerySet.create()方法上User實例:

  1. 如果您運行管理命令python manage.py sql,注意auth_user模式:

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

    在SQL中,一個空字符串,'' ,並不等同於NULL,即ISNULL('') != TRUE

  2. QuerySet.create() and QuerySet.update()不觸發模型驗證。模型驗證僅在ModelForm實例調用Model.full_clean()實例方法時發生。

    在使用QuerySet API的上下文中引發驗證錯誤直接在Django中毫無意義。這就是爲什麼你可以做類似User.objects.create(username='foo', password='')的東西,即使CharField().validate(value='', None)會爲空白字符串增加ValidationError

基於上述原因,你應該使用User.objects.create()推遲,依靠從模型的定製經理提供的User.objects.create_user()方法。

+0

不錯的擴展答案:-) – 2012-07-18 15:53:17

0

看Django的源用戶模型,有一個自定義的經理,片段:

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

我知道create_user不需要密碼。如果您通過一些外部來源進行身份驗證,它已經實施。我只是認爲這對用戶的經理create()方法不合適。 – sunprophit 2012-07-18 15:30:53

+1

不,因爲用戶定義了自定義管理器,但使用了相同的變量'objects'cre​​ate – 2012-07-18 15:43:05