1、forms組件javascript
2、cookie和session組件css
3、auth組件html
1、forms組件java
1.校驗字段功能python
針對一個實例:註冊用戶講解jquery
模型:models數據庫
class UserInfo(models.Model):
name=models.CharField(max_length=32)
pwd=models.CharField(max_length=32)
email=models.EmailField(
模板文件django
複製代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<div>
<label for="user">用戶名</label>
<p><input type="text" name="name" id="name"></p>
</div>
<div>
<label for="pwd">密碼</label>
<p><input type="password" name="pwd" id="pwd"></p>
</div>
<div>
<label for="r_pwd">確認密碼</label>
<p><input type="password" name="r_pwd" id="r_pwd"></p>
</div>
<div>
<label for="email">郵箱</label>
<p><input type="text" name="email" id="email"></p>
</div>
<input type="submit">
</form>
</body>
</html>
視圖函數編程
# forms組件
from django.forms import widgets
wid_01=widgets.TextInput(attrs={"class":"form-control"})
wid_02=widgets.PasswordInput(attrs={"class":"form-control"})
class UserForm(forms.Form):
name=forms.CharField(max_length=32,
widget=wid_01
)
pwd=forms.CharField(max_length=32,widget=wid_02)
r_pwd=forms.CharField(max_length=32,widget=wid_02)
email=forms.EmailField(widget=wid_01)
tel=forms.CharField(max_length=32,widget=wid_01)
def register(request):
if request.method=="POST":
form=UserForm(request.POST)
if form.is_valid():
print(form.cleaned_data) # 全部乾淨的字段以及對應的值
else:
print(form.cleaned_data) #
print(form.errors) # ErrorDict : {"校驗錯誤的字段":["錯誤信息",]}
print(form.errors.get("name")) # ErrorList ["錯誤信息",]
return HttpResponse("OK")
form=UserForm()
return render(request,"register.html",locals())
2.渲染標籤功能bootstrap
渲染方式1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h3>註冊頁面</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-lg-offset-3">
<form action="" method="post">
{% csrf_token %}
<div>
<label for="">用戶名</label>
{{ form.name }}
</div>
<div>
<label for="">密碼</label>
{{ form.pwd }}
</div>
<div>
<label for="">確認密碼</label>
{{ form.r_pwd }}
</div>
<div>
<label for=""> 郵箱</label>
{{ form.email }}
</div>
<input type="submit" class="btn btn-default pull-right">
</form>
</div>
</div>
</div>
</body>
</html>
渲染方式二
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
<div>
<label for="">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<input type="submit" class="btn btn-default pull-right">
</form>
渲染方式3、
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-default pull-right">
</form>
三、渲染錯誤信息功能
視圖
def register(request):
if request.method=="POST":
form=UserForm(request.POST)
if form.is_valid():
print(form.cleaned_data) # 全部乾淨的字段以及對應的值
else:
print(form.cleaned_data) #
print(form.errors) # ErrorDict : {"校驗錯誤的字段":["錯誤信息",]}
print(form.errors.get("name")) # ErrorList ["錯誤信息",]
return render(request,"register.html",locals())
form=UserForm()
return render(request,"register.html",locals()
模板
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>
<label for="">{{ field.label }}</label>
{{ field }} <span class="pull-right" style="color: red">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<input type="submit" class="btn btn-default">
</form>
組件參數配置
class Ret(Form):
name = forms.CharField(max_length=10, min_length=2, label='用戶名',
error_messages={'required': '該字段不能爲空', 'invalid': '格式錯誤', 'max_length': '太長',
'min_length': '過短'},
widget=widgets.TextInput(attrs={'class':'form-control'}))
pwd = forms.CharField(max_length=10, min_length=2, widget=widgets.PasswordInput(attrs={'class':'form-control'}))
email = forms.EmailField(label='郵箱', error_messages={'required': '該字段不能爲空', 'invalid': '格式錯誤'})
5.局部鉤子
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
def clean_name(self):
val=self.cleaned_data.get("name")
ret=UserInfo.objects.filter(name=val)
if not ret:
return val
else:
raise ValidationError("該用戶已註冊!")
def clean_tel(self):
val=self.cleaned_data.get("tel")
if len(val)==11:
return val
else:
raise ValidationError("手機號格式錯誤")
6.全局鉤子
def clean(self):
pwd=self.cleaned_data.get('pwd')
r_pwd=self.cleaned_data.get('r_pwd')
if pwd and r_pwd:
if pwd==r_pwd:
return self.cleaned_data
else:
raise ValidationError('兩次密碼不一致')
else:
return self.cleaned_data
pwd_err=my_form.errors.get('__all__')
from django import forms
from django.forms import widgets
from app01 import models
from django.core.exceptions import ValidationError
class RegForm(forms.Form):
name = forms.CharField(max_length=8, min_length=3, label='用戶名',
error_messages={'max_length': '太長了',
'min_length': '過短了',
'required': '該項不能爲空'
},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
pwd = forms.CharField(max_length=8, min_length=3, label='密碼',
error_messages={'max_length': '太長了',
'min_length': '過短了',
'required': '該項不能爲空'
},
widget=widgets.PasswordInput(attrs={'class': 'form-control'})
)
re_pwd = forms.CharField(max_length=8, min_length=3, label='確認密碼',
error_messages={'max_length': '太長了',
'min_length': '過短了',
'required': '該項不能爲空'
},
widget=widgets.PasswordInput(attrs={'class': 'form-control'})
)
email = forms.EmailField(label='郵箱', error_messages={'invalid': '格式不正確',
'required': '該項不能爲空'
},
widget=widgets.EmailInput(attrs={'class': 'form-control'})
)
# clean_字段名字
def clean_name(self):
# 從cleaned_data中取出字段的值
name = self.cleaned_data.get('name')
# # 校驗是否以sb開頭
if name.startswith('sb'):
raise ValidationError('不能以sb開頭')
else:
return name
# user = models.UserInfo.objects.filter(name=name).first()
# if user:
# # 用戶已經存在,校驗不經過,拋一個異常
# raise ValidationError('該用戶已經存在')
#
# else:
# # 校驗經過,返回要校驗的數據
# return name
# def clean_pwd(self):
# pass
# 全局鉤子函數(上面全部校驗規則都經過了,包括自定義的)
def clean(self):
pwd=self.cleaned_data.get('pwd')
re_pwd=self.cleaned_data.get('re_pwd')
if pwd==re_pwd:
# 正確,返回self.cleaned_data
return None
else:
# 校驗失敗,拋異常
raise ValidationError('兩次密碼不一致')
myfroms
from django.shortcuts import render, HttpResponse, redirect
# Create your views here.
from app01.MyForm import RegForm
def register(request):
if request.method == 'GET':
myform = RegForm()
else:
myform = RegForm(request.POST)
if myform.is_valid():
# 存數據庫,保存這我的
print(myform.cleaned_data)
else:
# 校驗不經過,這裏面也可能有值
# 總錯誤信息{'name':['太長了',],'pwd':['過短了']}
# print(myform.cleaned_data)
# 總錯誤
# myform.glo_err=myform.errors.get('__all__')
error_all = myform.errors.get('__all__')
# print()
# 每個的錯誤信息
# for item in myform:
# # ['太長了',]
# # print(item.errors[0])
# # print(type(item.errors))
# from django.forms.utils import ErrorList
# # print(item.errors.as_data())
# print(item.errors)
# # print(type(item.errors))
return render(request, 'register.html', locals())
視圖函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="/static/jquery-3.3.1.js"></script>
<title>註冊</title>
</head>
<body>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post" novalidate>
{% for foo in myform %}
<p>{{ foo.label }}:{{ foo }} <span class="pull-right">{{ foo.errors.0 }}</span></p>
{% endfor %}
<input type="submit" value="提交"><span>{{error_all.0 }}</span>
</form>
<hr>
<form action="" method="post" novalidate>
<p>用戶名:{{ myform.name }} <span>{{ myform.errors.name }}</span></p>
<p>用戶名:{{ myform.pwd }} <span>{{ myform.errors.pwd }}</span></p>
<p>用戶名:{{ myform.email }} <span>{{ myform.errors.email }}</span></p>
<input type="submit" value="提交">
</form>
</div>
</div>
</body>
</html>
模板
# 小結:
-forms組件的渲染錯誤信息
在模板中:<span>{{ foo.errors.0 }}</span>
-forms使用bootstrap樣式
widget=widgets.EmailInput(attrs={'class':'form-control'}))
-全局和局部鉤子函數
AOP:面向切面編程
-局部鉤子函數(再校驗name)
def clean_name(self):
# 從cleaned_data中取出字段的值
name = self.cleaned_data.get('name')
# # 校驗是否以sb開頭
if name.startswith('sb'):
raise ValidationError('不能以sb開頭')
else:
return name
-全局鉤子函數
def clean(self):
pwd=self.cleaned_data.get('pwd')
re_pwd=self.cleaned_data.get('re_pwd')
if pwd==re_pwd:
# 正確,返回self.cleaned_data
return self.cleaned_data
else:
# 校驗失敗,拋異常
raise ValidationError('兩次密碼不一致')
2、cookie和session組件
1.什麼是會話跟蹤
咱們須要瞭解下什麼叫作會話,能夠把會話理解成客戶端和服務器之間的一次會晤,在一次會晤中可能會包含屢次請求和響應。例如你給10086打電話,你就是客戶端,10086就是服務器。雙方接通電話的那一刻起,會話就開始,到某一方掛斷電話表示會話結束,在通話過程當中,你會向10086 發出不少請求,那麼這個請求就在一個會話中。
在一個會話的多個請求中共享數據,這就是會話跟蹤技術。例如在一個會話中的請求以下:
請求銀行主頁;
- 請求登陸(請求參數是用戶名和密碼);
- 請求轉帳(請求參數與轉帳相關的數據);
- 請求信譽卡還款(請求參數與還款相關的數據)。
在這上會話中當前用戶信息必須在這個會話中共享的,由於登陸的是張三,那麼在轉帳和還款時必定是相對張三的轉帳和還款!這就說明咱們必須在一個會話過程當中有共享數據的能力。
# 會話路徑技術使用cookie或session完成
咱們知道HTTP協議是無狀態協議,也就是說每一個請求都是獨立的!沒法記錄前一次請求的狀態。但HTTP協議中可使用Cookie來完成會話跟蹤!在Web開發中,使用session來完成會話跟蹤,session底層依賴Cookie技術。
2.cookie
cookie的由來
你們都知道HTTP協議是無狀態的。
無狀態的意思是每次請求都是獨立的,它的執行狀況和結果與前面的請求和以後的請求都無直接關係,它不會受前面的請求響應狀況直接影響,也不會直接影響後面的請求響應狀況。
一句有意思的話來描述就是人生只如初見,對服務器來講,每次的請求都是全新的。
狀態能夠理解爲客戶端和服務器在某次會話中產生的數據,那無狀態的就覺得這些數據不會被保留。會話中產生的數據又是咱們須要保存的,也就是說要「保持狀態」。所以Cookie就是在這樣一個場景下誕生。
# 什麼cookie
其實Cookie是key-value結構,相似於一個python中的字典。隨着服務器端的響應發送給客戶端瀏覽器。而後客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器時把Cookie再發送給服務器。 Cookie是由服務器建立,而後經過響應發送給客戶端的一個鍵值對。客戶端會保存Cookie,並會標註出Cookie的來源(哪一個服務器的Cookie)。當客戶端向服務器發出請求時會把全部這個服務器Cookie包含在請求中發送給服務器,這樣服務器就能夠識別客戶端了!
#cookie的原理
cookie的工做原理是:由服務器產生內容,瀏覽器收到請求後保存在本地,當瀏覽器再次訪問時,瀏覽器會自動帶上cookie,這樣服務器就能經過cookie的內容來判斷這個是誰了
#cookie規範
cookie大小上限爲4kb;
一個服務器最多在瀏覽器上保存20個cookie
一個瀏覽器上最多保存300個cookie
上面的數據只是http的cookie規範,可是瀏覽器大戰的今天,一些瀏覽器爲了戰勝對手,爲了展示本身的能力起見,可能對cookie規範擴展了一些,例如每一個cookie大小爲8kb,最多能夠保存500個kb等,但也不會出現把你的硬盤佔滿的可能!
注意,不一樣的瀏覽器之間是不共享cookie的,也就是說在你使用IE訪問瀏覽器時,服務器會把Cookie發給IE,而後由IE保存起來,當你在使用FireFox訪問服務器時,不可能把IE保存的Cookie發送給服務器。
#cookie的覆蓋
若是服務器發送重複大的cookie那麼會覆蓋原有的cookie,例如客戶端的第一個請求服務器端發送的cookie是:set-cookie:a=A;第二個請求服務器端發送的是:set-cookie:a=AA,那麼客戶端只留下一個cookie,即a=AA
# 在瀏覽器中查看cookie
瀏覽器中按F12,點network--cookies就能看到
django中操做cookie
# 獲取cookie
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
參數:
- default: 默認值
- salt: 加密鹽
- max_age: 後臺控制過時時間
# 設置cookie
rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value)
rep.set_signed_cookie(key,value,salt='加密鹽')
參數:
- key, 鍵
- value='', 值
- max_age=None, 超時時間 cookie須要延續的時間(以秒爲單位)若是參數是\ None`` ,這個cookie會延續到瀏覽器關閉爲止
- expires=None, 超時時間(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路徑,/ 表示根路徑,特殊的:根路徑的cookie能夠被任何url的頁面訪問,瀏覽器只會把cookie回傳給帶有該路徑的頁面,這樣能夠避免將cookie傳給站點中的其餘的應用。
- domain=None, Cookie生效的域名 你可用這個參數來構造一個跨站cookie。如, domain=".example.com"所構造的cookie對下面這些站點都是可讀的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。若是該參數設置爲 None ,cookie只能由設置它的站點讀取
- secure=False, 瀏覽器將經過HTTPS來回傳cookie
- httponly=False 只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)
#刪除cookie
def logout(request):
rep = redirect("/login/")
rep.delete_cookie("user") # 刪除用戶瀏覽器上以前設置的usercookie值
return rep
#cookie版登陸校驗
def login_auth(func):
def inner(request,*args,**kwargs):
next_url=request.get_full_path()
if request.COOKIES.get('is_login'):
return func(request,*args,**kwargs)
else:
return redirect('cookie_login/?next=%s'%next_url)
return inner
@login_auth
def cookie_order(request):
return HttpResponse('我是訂單頁面')
@login_auth
def cookie_index(request):
name=request.COOKIES.get('username')
return render(request,'cookie_index.html',{'name':name})
def cookie_login(request):
if request.method =='POST':
next_url=request.GET.get('next')
name=request.POST.get('name')
password=request.POST.get('password')
if name == 'lqz' and password == '123':
import datetime
now=datetime.datetime.now().strftime('%Y-%m-%d %X')
print(now)
obj=redirect(next_url)
obj.set_cookie('is_login',True)
obj.set_cookie('username',name)
obj.set_cookie('login_time',now)
return obj
return render(request, 'cookie_login.html')
登陸認證裝飾器
3.session
# session的由來
Cookie雖然在必定程度上解決了「保持狀態」的需求,可是因爲Cookie自己最大支持4096字節,以及Cookie自己保存在客戶端,可能被攔截或竊取,所以就須要有一種新的東西,它能支持更多的字節,而且他保存在服務器,有較高的安全性。這就是Session。
問題來了,基於HTTP協議的無狀態特徵,服務器根本就不知道訪問者是「誰」。那麼上述的Cookie就起到橋接的做用。
咱們能夠給每一個客戶端的Cookie分配一個惟一的id,這樣用戶在訪問時,經過Cookie,服務器就知道來的人是「誰」。而後咱們再根據不一樣的Cookie的id,在服務器上保存一段時間的私密資料,如「帳號密碼」等等。
總結而言:Cookie彌補了HTTP無狀態的不足,讓服務器知道來的人是「誰」;可是Cookie以文本的形式保存在本地,自身安全性較差;因此咱們就經過Cookie識別不一樣的用戶,對應的在Session裏保存私密的信息以及超過4096字節的文本。
另外,上述所說的Cookie和Session實際上是共通性的東西,不限於語言和框架。
#django中的session相關方法
# 獲取、設置、刪除Session中數據
request.session['k1']
request.session.get('k1',None)
request.session['k1'] = 123
request.session.setdefault('k1',123) # 存在則不設置
del request.session['k1']
# 全部 鍵、值、鍵值對
request.session.keys()
request.session.values()
request.session.items()
request.session.iterkeys()
request.session.itervalues()
request.session.iteritems()
# 會話session的key
request.session.session_key
# 將全部Session失效日期小於當前日期的數據刪除
request.session.clear_expired()
# 檢查會話session的key在數據庫中是否存在
request.session.exists("session_key")
# 刪除當前會話的全部Session數據(只刪數據庫)
request.session.delete()
# 刪除當前的會話數據並刪除會話的Cookie(數據庫和cookie都刪)。
request.session.flush()
這用於確保前面的會話數據不能夠再次被用戶的瀏覽器訪問
例如,django.contrib.auth.logout() 函數中就會調用它。
# 設置會話Session和Cookie的超時時間
request.session.set_expiry(value)
* 若是value是個整數,session會在些秒數後失效。
* 若是value是個datatime或timedelta,session就會在這個時間後失效。
* 若是value是0,用戶關閉瀏覽器session就會失效。
* 若是value是None,session會依賴全局session失效策略。
Django中使用session時,作的事:
# 生成隨機字符串
# 寫瀏覽器cookie -> session_id: 隨機字符串
# 寫到服務端session:
# {
# "隨機字符串": {'user':'alex'}
# }
# django中的session配置
1. 數據庫Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默認)
2. 緩存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
SESSION_CACHE_ALIAS = 'default' # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置
3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
SESSION_FILE_PATH = None # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir()
4. 緩存+數據庫
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
其餘公用設置項:
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認)
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時(默認)
SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存(默認)
思考,若是第二人再次在同一個瀏覽器上登陸,django-session表會怎樣
# CBV中加裝飾器
from django import views
from django.utils.decorators import method_decorator
# @method_decorator(login_auth,name='get')
# @method_decorator(login_auth,name='post')
class UserList(views.View):
# @method_decorator(login_auth)
def dispatch(self, request, *args, **kwargs):
obj=super().dispatch(request, *args, **kwargs)
return obj
@method_decorator(login_auth)
def get(self,request):
return HttpResponse('我是用戶列表')
def post(self,request):
return HttpResponse('我是用戶列表')
3、auth組件
1.Auth模塊是什麼
Auth模塊是Django自帶的用戶認證模塊:
咱們在開發一個網站的時候,無可避免的須要設計實現網站系統,此時咱們須要實現包括用戶註冊、用戶登陸、用戶認證、註銷、修改密碼等功能,這還真是個麻煩的事情
Django做爲一個完美主義者的終極框架,固然也會想到用戶的這些痛點。它內置了強大的用戶認證系統--auth,它默認使用 auth_user 表來存儲用戶數據。
2.auth模塊經常使用方法
導入模塊
from django.contrib import auth
#authenticate()
提供了用戶認證功能,即驗證用戶名以及密碼是否正確,通常須要username 、password兩個關鍵字參數。
若是認證成功(用戶名和密碼正確有效),便會返回一個 User 對象。
authenticate()會在該 User 對象上設置一個屬性來標識後端已經認證了該用戶,且該信息在後續的登陸過程當中是須要的。
用法:
user = authenticate(username='usernamer',password='password')
#login(HttpRequest,user)
該函數接受一個HttpRequest對象,以及一個通過認證的User對象。
該函數實現一個用戶登陸的功能。它本質上會在後端爲該用戶生成相關session數據。
用法:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
#logout(request)
該函數接受一個HttpRequest對象,無返回值
當調用該函數時,當前請求的session信息會所有清除,該用戶即便沒有登陸,使用該函數也不會報錯,
用法:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
# is_authenticated()
用來判斷當前請求是否經過了認證。
用法:
def my_view(request):
if not request.user.is_authenticated():
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
#login_requier()
auth給咱們提供的一個裝飾工具,用來快捷的給某個函數圖添加登陸校驗
用法:
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
若用戶沒有登陸,則會跳轉到django默認的 登陸URL '/accounts/login/ ' 並傳遞當前訪問url的絕對路徑 (登錄成功後,會重定向到該路徑)。
若是須要自定義登陸的URL,則須要在settings.py文件中經過LOGIN_URL進行修改。
示例:
LOGIN_URL = '/login/' # 這裏配置成你項目登陸頁面的路由
#create_user()
auth提供一個建立新用戶的方法,須要提供必要參數(username、password)等
用法
from django.contrib.auth.models import User
user = User.objects.create_user(username='用戶名',password='密碼',email='郵箱',...)
#create_superuser()
auth提供的一個建立的超級用戶的方法,須要提供必要的參數(username、password)等
用法
from django.contrib.auth.models import User
user = User.objects.create_superuser(username='用戶名',password='密碼',email='郵箱',...)
#check_password(password)
auth 提供的一個檢查密碼是否正確的方法,須要提供當前請求用戶的密碼。
密碼正確返回True,不然返回False。
用法:
ok = user.check_password('密碼')
1 Auth模塊是什麼
Auth模塊是Django自帶的用戶認證模塊:
咱們在開發一個網站的時候,無可避免的須要設計實現網站的用戶系統。此時咱們須要實現包括用戶註冊、用戶登陸、用戶認證、註銷、修改密碼等功能,這還真是個麻煩的事情呢。
Django做爲一個完美主義者的終極框架,固然也會想到用戶的這些痛點。它內置了強大的用戶認證系統--auth,它默認使用 auth_user 表來存儲用戶數據。
2 auth模塊經常使用方法
from django.contrib import auth
authenticate()
提供了用戶認證功能,即驗證用戶名以及密碼是否正確,通常須要username 、password兩個關鍵字參數。
若是認證成功(用戶名和密碼正確有效),便會返回一個 User 對象。
authenticate()會在該 User 對象上設置一個屬性來標識後端已經認證了該用戶,且該信息在後續的登陸過程當中是須要的。
用法:
user = authenticate(username='usernamer',password='password')
login(HttpRequest, user)
該函數接受一個HttpRequest對象,以及一個通過認證的User對象。
該函數實現一個用戶登陸的功能。它本質上會在後端爲該用戶生成相關session數據。
用法:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
logout(request)
該函數接受一個HttpRequest對象,無返回值。
當調用該函數時,當前請求的session信息會所有清除。該用戶即便沒有登陸,使用該函數也不會報錯。
用法:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
is_authenticated()
用來判斷當前請求是否經過了認證。
用法:
def my_view(request):
if not request.user.is_authenticated():
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
login_requierd()
auth 給咱們提供的一個裝飾器工具,用來快捷的給某個視圖添加登陸校驗。
用法:
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
若用戶沒有登陸,則會跳轉到django默認的 登陸URL '/accounts/login/ ' 並傳遞當前訪問url的絕對路徑 (登錄成功後,會重定向到該路徑)。
若是須要自定義登陸的URL,則須要在settings.py文件中經過LOGIN_URL進行修改。
示例:
LOGIN_URL = '/login/' # 這裏配置成你項目登陸頁面的路由
create_user()
auth 提供的一個建立新用戶的方法,須要提供必要參數(username、password)等。
用法:
from django.contrib.auth.models import User
user = User.objects.create_user(username='用戶名',password='密碼',email='郵箱',...)
create_superuser()
auth 提供的一個建立新的超級用戶的方法,須要提供必要參數(username、password)等。
用法:
from django.contrib.auth.models import User
user = User.objects.create_superuser(username='用戶名',password='密碼',email='郵箱',...)
check_password(password)
auth 提供的一個檢查密碼是否正確的方法,須要提供當前請求用戶的密碼。
密碼正確返回True,不然返回False。
用法:
ok = user.check_password('密碼')
set_password(password)
auth 提供的一個修改密碼的方法,接收 要設置的新密碼 做爲參數。
注意:設置完必定要調用用戶對象的save方法!!!
用法:
user.set_password(password='')
user.save()
@login_required
def set_password(request):
user = request.user
err_msg = ''
if request.method == 'POST':
old_password = request.POST.get('old_password', '')
new_password = request.POST.get('new_password', '')
repeat_password = request.POST.get('repeat_password', '')
# 檢查舊密碼是否正確
if user.check_password(old_password):
if not new_password:
err_msg = '新密碼不能爲空'
elif new_password != repeat_password:
err_msg = '兩次密碼不一致'
else:
user.set_password(new_password)
user.save()
return redirect("/login/")
else:
err_msg = '原密碼輸入錯誤'
content = {
'err_msg': err_msg,
}
return render(request, 'set_password.html', content)
修改過的簡單事例
#User對象屬性
User對象屬性:username, password
is_staff : 用戶是否擁有網站的管理權限.
is_active : 是否容許用戶登陸, 設置爲 False,能夠在不刪除用戶的前提下禁止用戶登陸。
3.擴展默認的auth_user表
這內置的認證系統這麼好用,可是auth_user表字段都是固定的那幾個,我在項目中無法拿來直接使用啊!
好比,我想要加一個存儲用戶手機號的字段,怎麼辦?
聰明的你可能會想到新建另一張表而後經過一對一和內置的auth_user表關聯,這樣雖然能知足要求可是有沒有更好的實現方式呢?
答案是固然有了。
咱們能夠經過繼承內置的 AbstractUser 類,來定義一個本身的Model類。
這樣既能根據項目需求靈活的設計用戶表,又能使用Django強大的認證系統了。
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
"""
用戶信息表
"""
nid = models.AutoField(primary_key=True)
phone = models.CharField(max_length=11, null=True, unique=True)
def __str__(self):
return self.username
注意:
按上面的方式擴展內置的auth_user表以後,必定要在settings.py中告訴Django,我如今使用我新定的User表來作用戶認證,寫法以下:
# 引用Django自帶的User表,繼承使用時須要設置
AUTH_USER_MODEL = "app名.UserInfo"
再次注意:
一旦咱們指定了新的認證系統所使用的表,咱們就須要從新在數據庫中建立該表,而不能繼續使用原來默認的auth_user表了