選擇使用django默認使用的db.sqlite
1.下載驅動
2.點擊files選框的...按鈕那里,選擇對應項目根目錄下的db.sqlite
3.Python3 manage.py migrate
4.Python3 manage.py createsuperuser,就可以在命令行創建一個超級用戶的賬戶
導入auth模塊
from django.contrib import auth
方法(部分)
authenticate()
這是用於驗證用戶名以及密碼是否正確,一般需要username password兩個關鍵字參數
如果驗證通過,會返回一個 User 對象。authenticate()會在User 對象上設置一個屬性來標識后端已經認證了該用戶,且該信息在后續的登錄過程中是需要的。
用法:user = authenticate(username='user',password='password')
當我們試圖登陸一個從數據庫中直接取出來不經過authenticate()的User對象時會報錯!!!
login(request, user)
該函數接受一個HttpRequest對象,以及一個認證了的User對象.此函數使用django的session框架給某個已認證的用戶附加上session id等信息。
1 from django.contrib.auth import authenticate, login 2 3 4 def my_view(request): 5 6 username = request.POST['username'] 7 8 password = request.POST['password'] 9 10 user = authenticate(username=username, password=password) 11 12 if user is not None: 13 14 login(request, user) 15 16 # Redirect to a success page. 17 18 ... 19 20 else: 21 22 # Return an 'invalid login' error message. 23 24 ...
logout(request) 注銷用戶
from django.contrib.auth import logout def logout(request): auth.logout(request) return redirect("/login/")
該函數接受一個HttpRequest對象,無返回值。當調用該函數時,當前請求的session信息會全部清除。該用戶即使沒有登錄,使用該函數也不會報錯。
is_authenticated()
用於判斷當前請求是否通過了認證
def my_view(request): if not request.user.is_authenticated(): return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
login_requierd()
用於快捷地給某個視圖添加登錄校驗
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...
若用戶沒有登錄,則會跳轉到django默認的 登錄URL '/accounts/login/ ' (這個值可以在settings.py文件中通過LOGIN_URL進行修改)。
# 設置這個網站默認登錄的頁面
LOGIN_URL = "/login/"
並傳遞當前訪問url的絕對路徑 (登陸成功后,會重定向到該路徑)。
User對象
User 對象屬性:username, password(必填項)password用哈希算法保存到數據庫
is_staff : 用戶是否擁有網站的管理權限.
is_active : 是否允許用戶登錄, 設置為``False``,可以不用刪除用戶來禁止 用戶登錄
is_authenticated()如果是真正的 User 對象,返回值恆為 True 。 用於檢查用戶是否已經通過了認證。通過認證並不意味着用戶擁有任何權限,這個方法甚至也不檢查該用戶是否處於激活狀態,只是表明用戶成功的通過了認證。
創建用戶
使用 create_user() 輔助函數創建用戶:
from django.contrib.auth.models import User user = User.objects.create_user(username='用戶名',password='密碼',email='郵件地址')
check_password(passwd)
用戶需要修改密碼的時候,首先要讓其輸入原來的密碼 ,如果給定的值通過了密碼檢查,返回 True
ok = user.check_password('密碼')
set_password()
用於修改密碼
user = User.objects.get(username='用戶名') user.set_password(password='設置的密碼') user.save()
設置完密碼后,一定要調用用戶對象的save方法保存修改后的
1 @login_required 2 def set_password(request): 3 user = request.user 4 err_msg = '' 5 if request.method == 'POST': 6 old_password = request.POST.get('old_password', '') 7 new_password = request.POST.get('new_password', '') 8 repeat_password = request.POST.get('repeat_password', '') 9 # 檢查舊密碼是否正確 10 if user.check_password(old_password): 11 if not new_password: 12 err_msg = '新密碼不能為空' 13 elif new_password != repeat_password: 14 err_msg = '兩次密碼不一致' 15 else: 16 user.set_password(new_password) 17 user.save() 18 return redirect("/login/") 19 else: 20 err_msg = '原密碼輸入錯誤' 21 content = { 22 'err_msg': err_msg, 23 } 24 return render(request, 'set_password.html', content) 25 26
擴展auth_user表
繼承內置的auth_user表的對應的類,來定義一個自己的ORM類。
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,我現在使用我新定義的UserInfo表來做用戶認證。寫法如下:
# 引用Django自帶的User表,繼承使用時需要設置 AUTH_USER_MODEL = "app名.UserInfo"
將Django的form組件和認證放在一起的小栗子:
1 from django.shortcuts import render, redirect, HttpResponse 2 from django.contrib import auth 3 from django.contrib.auth.models import User 4 from django.contrib.auth.decorators import login_required 5 from about_auth import froms 6 7 8 # Create your views here. 9 def login(request): 10 if request.method == 'POST': 11 form_obj = froms.LoginForm(request.POST) 12 if form_obj.is_valid(): 13 dic = form_obj.cleaned_data 14 # 驗證用戶名和密碼是否正確 15 user = auth.authenticate(username=dic["username"], password=dic["password"]) 16 if user: 17 # 調用內置的login方法 18 # 1.生成session數據,把session寫入cookie 19 # 后來每次進來的時候,request.user拿到當前值 20 auth.login(request, user) 21 return redirect('/home/') 22 else: 23 print(form_obj) 24 return render(request,'login.html',{'form_obj':form_obj, }) 25 form_obj = froms.LoginForm() 26 return render(request, 'login.html', {'form_obj': form_obj}) 27 28 29 def register(request): 30 if request.method == 'POST': 31 form_obj = froms.RegForm(request.POST) 32 if form_obj.is_valid(): 33 # 創建普通用戶的專用方法 34 User.objects.create_user(username=form_obj.cleaned_data["username"], 35 password=form_obj.cleaned_data["password"]) 36 return redirect("/login/") 37 else: 38 return render(request, 'register.html', {'form_obj': form_obj}) 39 form_obj = froms.RegForm() 40 return render(request, 'register.html', {'form_obj': form_obj}) 41 42 43 @login_required 44 def home(request): 45 return render(request, 'home.html') 46 47 48 @login_required 49 def set_pwd(request): 50 if request.method == 'POST': 51 form_obj = froms.SetPwdForm(request.POST) 52 if form_obj.is_valid(): 53 dic = form_obj.cleaned_data 54 # 先校驗原密碼對不對 55 user_obj = request.user 56 if user_obj.check_password(dic["old_pwd"]): 57 if dic["new_pwd"] == dic["con_pwd"]: 58 # 修改原密碼 59 user_obj.set_password(dic["new_pwd"]) 60 user_obj.save() 61 return redirect('/login/') 62 else: 63 return HttpResponse("原密碼錯誤") 64 form_obj = froms.SetPwdForm() 65 return render(request, 'set_pwd.html', {'form_obj': form_obj, }) 66 67 68 def logout(request): 69 auth.logout(request) 70 return redirect("/login/")
1 from django import forms 2 3 4 class RegForm(forms.Form): 5 username = forms.CharField( 6 min_length=3, 7 label='用戶名', 8 error_messages={ 9 'required': '用戶名不能為空', 10 'min_length': '用戶名最少不能少於三個字符', 11 }, 12 widget=forms.widgets.TextInput(attrs={'class': 'form-control', }) 13 ) 14 password = forms.CharField( 15 min_length=6, 16 label='密碼', 17 error_messages={ 18 'required': '密碼不能為空', 19 'min_length': '密碼不能少於6位數', 20 }, 21 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 22 ) 23 con_pwd = forms.CharField( 24 min_length=6, 25 label='確認密碼', 26 error_messages={ 27 'required': '密碼不能為空', 28 'min_length': '密碼不能少於6位數', 29 }, 30 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 31 ) 32 33 34 class LoginForm(forms.Form): 35 username = forms.CharField( 36 min_length=3, 37 label='用戶名', 38 error_messages={ 39 'required': '用戶名不能為空', 40 'min_length': '用戶名最少不能少於三個字符', 41 }, 42 widget=forms.widgets.TextInput(attrs={'class': 'form-control', }) 43 ) 44 password = forms.CharField( 45 min_length=6, 46 label='密碼', 47 error_messages={ 48 'required': '密碼不能為空', 49 'min_length': '密碼不能少於6位數', 50 }, 51 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 52 ) 53 54 55 class SetPwdForm(forms.Form): 56 old_pwd = forms.CharField( 57 min_length=6, 58 label='原密碼', 59 error_messages={ 60 'required': '密碼不能為空', 61 'min_length': '密碼不能少於6位數', 62 }, 63 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 64 ) 65 new_pwd = forms.CharField( 66 min_length=6, 67 label='新密碼', 68 error_messages={ 69 'required': '密碼不能為空', 70 'min_length': '密碼不能少於6位數', 71 }, 72 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 73 ) 74 con_pwd = forms.CharField( 75 min_length=6, 76 label='確認密碼', 77 error_messages={ 78 'required': '密碼不能為空', 79 'min_length': '密碼不能少於6位數', 80 }, 81 widget=forms.widgets.PasswordInput(attrs={'class': 'form-control', }) 82 )
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>注冊</title> 7 <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css"> 8 <style type="text/css"> 9 .top{ 10 margin-top: 5%; 11 } 12 </style> 13 </head> 14 <body> 15 <div class="container-fluid"> 16 <div class="row"> 17 <div class="top col-md-4 col-md-offset-4"> 18 <div class="panel panel-danger"> 19 <div class="panel-heading"> 20 <h3 class="panel-title"><strong>歡迎注冊</strong></h3> 21 </div> 22 <div class="panel-body"> 23 <form action="" method="post" novalidate autocomplete="off"> 24 {% csrf_token %} 25 <div class="form-group"> 26 <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> 27 {{ form_obj.username }} 28 <span class="help-block">{{ form_obj.username.errors.0 }}</span> 29 </div> 30 <div class="form-group"> 31 <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label> 32 {{ form_obj.password }} 33 <span class="help-block">{{ form_obj.password.errors.0 }}</span> 34 </div> 35 <div class="form-group"> 36 <label for="{{ form_obj.con_pwd.id_for_label }}">{{ form_obj.con_pwd.label }}</label> 37 {{ form_obj.con_pwd }} 38 <span class="help-block">{{ form_obj.con_pwd.errors.0 }}</span> 39 </div> 40 <button type="submit" class="btn btn-default btn-block">注冊</button> 41 </form> 42 </div> 43 </div> 44 </div> 45 </div> 46 </div> 47 </body> 48 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>登錄</title> 7 <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css"> 8 <style type="text/css"> 9 .top{ 10 margin-top: 5%; 11 } 12 </style> 13 </head> 14 <body> 15 <div class="container-fluid"> 16 <div class="row"> 17 <div class="top col-md-4 col-md-offset-4"> 18 <div class="panel panel-primary"> 19 <div class="panel-heading"> 20 <h3 class="panel-title"><strong>歡迎登錄</strong></h3> 21 </div> 22 <div class="panel-body"> 23 <form action="" method="post" novalidate autocomplete="off"> 24 {% csrf_token %} 25 <div class="form-group"> 26 <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label> 27 {{ form_obj.username }} 28 <span class="help-block">{{ form_obj.username.errors.0 }}</span> 29 </div> 30 <div class="form-group"> 31 <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label> 32 {{ form_obj.password }} 33 <span class="help-block">{{ form_obj.password.errors.0 }}</span> 34 </div> 35 <button type="submit" class="btn btn-default btn-block">登錄</button> 36 </form> 37 </div> 38 </div> 39 </div> 40 </div> 41 </div> 42 </body> 43 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>home</title> 7 8 </head> 9 <body> 10 <h1>你好,用戶{{ request.user.username }}</h1> 11 <a href="/logout/">注銷</a> 12 <a href="/set_pwd/">修改密碼</a> 13 </body> 14 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>重置密碼</title> 7 <link rel="stylesheet" href="../static/bootstrap-3.3.7/css/bootstrap.min.css"> 8 <style type="text/css"> 9 .top{ 10 margin-top: 5%; 11 } 12 </style> 13 </head> 14 <body> 15 <div class="container-fluid"> 16 <div class="row"> 17 <div class="top col-md-4 col-md-offset-4"> 18 <div class="panel panel-danger"> 19 <div class="panel-heading"> 20 <h3 class="panel-title"><strong>重置密碼</strong></h3> 21 </div> 22 <div class="panel-body"> 23 <form action="" method="post" novalidate autocomplete="off"> 24 {% csrf_token %} 25 <div class="form-group"> 26 <label for="{{ form_obj.old_pwd.id_for_label }}">{{ form_obj.old_pwd.label }}</label> 27 {{ form_obj.old_pwd }} 28 <span class="help-block">{{ form_obj.old_pwd.errors.0 }}</span> 29 </div> 30 <div class="form-group"> 31 <label for="{{ form_obj.new_pwd.id_for_label }}">{{ form_obj.new_pwd.label }}</label> 32 {{ form_obj.new_pwd }} 33 <span class="help-block">{{ form_obj.new_pwd.errors.0 }}</span> 34 </div> 35 <div class="form-group"> 36 <label for="{{ form_obj.con_pwd.id_for_label }}">{{ form_obj.con_pwd.label }}</label> 37 {{ form_obj.con_pwd }} 38 <span class="help-block">{{ form_obj.con_pwd.errors.0 }}</span> 39 </div> 40 <button type="submit" class="btn btn-default btn-block">確認</button> 41 </form> 42 </div> 43 </div> 44 </div> 45 </div> 46 </div> 47 </body> 48 </html>
