django提供了一套用戶驗證系統,可是要使用這個系統,必需要使用django內置的用戶模型:django.contrib.auth.models.User,這個模型中預先定義了一些字段,其中只有username和password是必須的。
username
用戶名,該字段是必須的,長度限制版本之間可能存在差別,1.10爲150個字符之內(其餘版本爲30個字符,存在版本差別)。能夠是字母、數字、+、-、_、.、@。這幾個字符。在1.10版本中,django正式支持utf-8的用戶名(也就是不受字符限制了),固然前提是要使用python3.x的版本。
固然,你也可使用max_length、min_length等屬性來控制用戶名的長短限制。下面的字段基本也適用。
固然咱們也能夠改變驗證器,例如將python3的驗證器改爲ASCII的:
from django.contrib.auth.models import User
from django.contrib.auth.validators import ASCIIUsernameValidator
class CustomUser(User):
username_validator = ASCIIUsernameValidator()
class Meta:
proxy = True # If no new field is added.
上面咱們首先子類化了User model,而後改變了username_validator屬性,這也是標準的修改步驟。
password
密碼,必須。django不會直接儲存原始密碼,而是儲存通過處理以後的哈希值。因此在建立用戶或修改密碼的時候不能直接操做這個屬性,而是使用django提供的專門的方法,下面會再說明。
email
可選,表示email地址。
first_name
可選,30個字符之內(在中文環境中應該用不上)
last_name
可選,30個字符之內
groups
Many-to-many relationship to
Group
user_permissions
關於權限的問題須要另外說明,這裏暫時不討論。
is_active
表用戶是不是活躍的,是一個布爾值。django提議與其刪除一個用戶的全部信息,還不如將其設置爲非活躍(即凍結)狀態。這樣不會破壞其餘相關的外鍵關係,同時也擁有了後悔的可能。
注意:在1.10以前,django的後臺驗證程序不會檢查用戶是否處於活躍狀態,也就是非活躍的用戶依然能夠登陸,此時要本身進行狀態驗證,例如:
if user.is_active: # 若用戶是活躍的,即未凍結的,在1.10以前凍結用戶默認也能登陸,因此須要本身認證
login(request, user) # 登陸
...... #其餘處理
else:
return HttpResponse('用戶被凍結')
在1.10版本中,django的默認驗證後臺會拒絕凍結用戶的訪問了。當凍結的用戶登陸時,會沒法經過
authenticate(username=None, password=None, **kwargs) 的驗證,即該方法會返回None。
is_staff
是否爲staff身份,布爾值。擁有staff身份的用戶能夠登陸django的admin後臺,且可使用
staff_member_required(redirect_field_name='next', login_url='admin:login') 裝飾器來進行訪問控制。詳情參考
django-訪問控制 篇。
is_superuser
是不是superuser身份,布爾值。擁有該身份的用戶將可以登陸admin後臺,並擁有全部註冊模型的管理權限。
last_login
用戶最後登陸的時間。
date_joined
用戶建立的時間。
以上就是django自帶的用戶認證系統使用的模型的所有字段了,也就是說django在數據庫中儲存的字段信息就是以上這些,若是須要擴展的話,有兩種方法:
1.另外再寫一個模型,用OneToOne的形式關聯到User中:
from django.db import models
from django.contrib.auth.models import User
class UserInfo(models.Model):
user = models.OneToOneField(User)
head_img = models.ImageField()
# 其它擴展
2.另寫一個模型,直接繼承User:
from django.db import models
from django.contrib.auth.models import User
class UserInfo(User):
head_img = models.ImageField()
# 其它擴展
不管哪一種方法均可以,由於那些已經定義好的字段都是儲存在User表中的,而新增的字段儲存在另外的表中,只是使用OneToOne的時候,查詢的入口略麻煩了些,詳情參考django的models。
用戶註冊:
所謂的用戶註冊,其實就是在User表中新建立一條記錄,而前面說過了,password字段儲存的不是原始密碼,而是加密後的字符串,因此不能直接對User對象的屬性進行修改,而是要調用專用的函數:
>>> from django.contrib.auth.models import User >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
此時,用戶就已經建立
並放到數據庫中了,這個方法比較特別,其自動爲咱們保存數據。
密碼修改:
因爲密碼字段不能直接操做,因此django也提供了函數專門用來修改密碼:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username='john')
>>> u.set_password('new password')
>>> u.save()
這裏有一個細節,它不像建立帳戶同樣會直接保存的數據庫中,而是調用User對象的save()方法,表示將修改保存到數據庫中。
資料修改:
其餘的字段能夠經過直接修改對象屬性的方法來修改數據,而後調用保存方法。
例如,我想修改用戶的email:
request.user.email = date['email'] # date的表單提交上來的數據
request.user.save() # 保存修改
通常資料修改須要用戶登陸以後才能修改,而登陸後的用戶能夠是使用request.user來獲取當前登陸的用戶,而後咱們直接對其email屬性進行修改,數據來自於用戶提交的表單(你能夠直接將其當作'scolia@example.com'這樣的直接的字面量)。最後咱們調用其save方法,其實除了password相關的操做須要調用輔助函數以外,其餘的基本都能這樣修改,這也是模型數據修改的典型方法。
用戶驗證:
要實現咱們日常須要的驗證登陸的功能,須要兩個步驟,第一步是驗證用戶名和密碼是否正確,第二步將用戶登陸。
from django.contrib.auth import authenticate
user = authenticate(username=date['user_name'], password=date['password'])
username和password兩個參數分別接受要登陸用戶的用戶名和密碼,這裏傳的是明文。
若驗證經過,其會返回User對象,這個User對象記錄了所用的用戶信息,你能夠對這個對象進行資料的修改等之類的操做。
若登陸失敗則返回None。
用戶登陸:
驗證成功以後,就能夠進行登陸操做了,django提供了專門的登陸函數來處理這個工做:
from django.contrib.auth import authenticate, login
user = authenticate(username=date['user_name'], password=date['password'])
if user is not None:
login(request, user)
#.....
else:
return HttpResponse('用戶名或密碼錯誤')
這裏的核心思想就是登陸失敗後,返回的是None,而判斷到user不爲None,即驗證成功了,就能夠
進行登陸操做了,不然返回錯誤。
這裏詳細的瞭解一下login這個函數:
login(request, user, backend=None)
其中request要求的是HttpRequest對象,也就是視圖的第一個參數所接受到的對象,習慣性的使用request,user要求要登陸的User對象,也就是驗證成功後返回的User對象。backend是1.10中新增的,其做用是指定特色的後臺程序,通常用不着,如有特殊需求能夠參考django1.10的官方文檔。
因爲HTTP協議是無狀態協議,因此使用的拓展的cookie和session首部來進行狀態記錄,django採用的是session,在登陸成功後,django會給客戶端設置session首部,其通常是一個用戶的ID,而不是用戶的詳細信息。客戶端登陸後訪問時都會回送這個ID,django接受到ID後找到對應的用戶,從而得知當前的訪問是哪一個用戶。實現了登陸的功能。
用戶註銷:
上面說過用戶的狀態是經過session來記錄的,也就是將session設置爲空後,即丟失登陸狀態,這就是註銷了。django一樣提供了變量的函數來完成這個工做:
from django.contrib.auth import logout
def logout_view(request):
logout(request) # Redirect to a success page.
讓咱們來認識一下這個函數:
logout(request)
其接收的只有一個參數,也就是當前的request對象。其所完成的就是重置session的工做。若是用戶沒有登陸,也不會報錯。
注意:這個仍是會清空全部的session,也就是說若是你有不但願被刪除的session的話,要先獲取到相應的session,並在調用logout以後再將其收到添加進去。