2012-07-18 30 views
5

Tôi đã gặp phải một số hành vi đáng ngờ của phương thức create() của User trình quản lý đối tượng. Có vẻ như trường password không bắt buộc để tạo đối tượng User nếu bạn sử dụng phương pháp này. Kết quả là bạn nhận được User với trống password. Trong trường hợp khi bạn sử dụng phương thức create_user và không chỉ định password, nó sẽ tạo User bằng mật khẩu không sử dụng được (qua số set_unusable_password()).Phương thức quản lý người dùng tạo() và create_user()

Tôi không chắc tại sao phương pháp create() không raise exception khi bạn cố gắng tạo người dùng mà không cần password - trong tài liệu được chỉ định rằng trường này là bắt buộc. Có gì sai trong phương pháp/tài liệu create() không?

Trả lời

9

Đó chính xác là lý do tại sao các mô hình người dùng có một người quản lý tuỳ chỉnh với một phương pháp UserManager.create_user() để tạo người sử dụng. Có hai vấn đề với việc sử dụng các phương pháp QuerySet.create() trên User trường hợp:

  1. Nếu bạn chạy các lệnh quản lý python manage.py sql, chú ý đến các schema auth_user:

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

    Trong SQL, một chuỗi rỗng, '' , không tương đương với NULL, tức là ISNULL('') != TRUE.

  2. QuerySet.create()QuerySet.update()không kích hoạt xác thực mô hình. Xác thực mẫu chỉ xảy ra khi ModelForm trường hợp gọi phương thức thể hiện Model.full_clean().

    Tăng lỗi xác thực trong ngữ cảnh làm việc với API QuerySet trực tiếp chỉ đơn giản là không có ý nghĩa trong Django. Đó là lý do tại sao bạn có thể làm điều gì đó như User.objects.create(username='foo', password='') mặc dù CharField().validate(value='', None) sẽ tăng một số ValidationError cho một chuỗi trống.

Vì những lý do trên, bạn nên trì hoãn từ việc sử dụng User.objects.create() và dựa trên cung cấp User.objects.create_user() phương pháp từ người quản lý tuỳ chỉnh của mô hình.

+0

câu trả lời mở rộng tốt đẹp :-) –

0

Nhìn vào mô hình nguồn tài django của, có một người quản lý tùy chỉnh, đoạn mã:

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

Tôi hiểu rằng mật khẩu không bắt buộc đối với create_user. Nó đã được thực hiện nếu bạn xác thực đối với một số nguồn bên ngoài. Tôi chỉ nghĩ rằng đó không phải là hành vi thích hợp cho phương thức create() của người quản lý. – sunprophit

+1

Không, bởi vì người dùng có một người quản lý tùy chỉnh được xác định nhưng sử dụng cùng một biến 'đối tượng' tạo ra –

Các vấn đề liên quan