Django有一個內置的受權系統:包括驗證和受權兩個部分。用來處理用戶、分組、權限以及基於cookie的會話系統。html
驗證:驗證這個用戶是不是他聲稱的人(好比用戶名和密碼驗證,角色驗證)python
受權:給與他相應的權限。數據庫
Django內置的權限系統:django
受權系統:默認中建立完一個django項目後,就已經集成了受權系統。cookie
INSTALLED_APPS:session
中間件:框架
SessionMiddleware:用來管理session。
AuthenticationMiddleware:用來處理和當前session相關聯的用戶。post
User模型
網站
該框架的核心部分。完整的路徑 django.contrib.auth.models.User ui
內置的User模型擁有的字段:
基本用法:
1 from django.http import HttpResponse 2 from django.contrib.auth.models import User 3 4 def index(request): 5 # 建立普通用戶 6 user = User.objects.create_user(username='jack',email='jack@123.com',password='111111') 7 # 建立超級用戶 8 user = User.objects.create_superuser(username='Alen', email='Alen@123.com', password='111111') 9 return HttpResponse('success')
修改密碼:
密碼是須要通過加密後才能存儲進去的。不能直接修改 password 字段,須要調用 set_password 來修改密碼。
1 user = User.objects.get(pk=1) 2 user.set_password('填寫新密碼') 3 user.save()
登陸驗證:
Django的驗證系統已經經過 django.contrib.auth.authenticate 實現了登陸驗證的功能。該方法只能經過 username 和 password 來進行驗證。
1 from django.contrib.auth import authenticate 2 3 def index(request): 4 username = 'jack' 5 password = '111111' 6 user = authenticate(request,username=username,password=password) 7 if user: 8 print('登陸成功:%s'% username) 9 else: 10 print('用戶名或密碼錯誤!') 11 return HttpResponse('success')
擴展用戶模型:
在驗證用戶登陸的時候,用的是用戶名做爲驗證,而有時候須要經過手機號碼或者郵箱來進行驗證。或者須要增長一些新的字段。這時就須要擴展用戶模型。
1 from django.db import models 2 from django.contrib.auth.models import User 3 4 # 使用代理模型,不能添加新的Field;可加新屬性; 5 class Person(User): 6 class Meta: 7 proxy = True 8 #增長黑名單屬性; 9 @classmethod 10 def get_blacklsit(cls): 11 return cls.objects.filter(is_active=False)
1 from .models import Person 2 from django.contrib.auth.models import User 3 from django.http import HttpResponse 4 5 # 提取數據表單中「is_active=0」的黑名單數據;(‘auth_user’表單已存儲數據) 6 def get_blacklist(request): 7 black_list = Person.get_blacklsit() 8 for person in black_list: 9 print(person.username) 10 return HttpResponse('proxy')
定義了一個 Person類 ,繼承自 User ,Meta 中設置 proxy=True ,說明這只是 User 的一個代理模型。不影響原來User模型在數據庫中表的結構。且 User.objects.all() 和 Person.objects.all() 是等價的。都是從User這個模型中獲取全部的數據。
1 from django.db import models 2 from django.contrib.auth.models import User 3 from django.dispatch import receiver 4 from django.db.models.signals import post_save 5 6 # 使用一對一外鍵擴展 7 class UserExtension(models.Model): 8 user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='extension') 9 telephone = models.CharField(max_length=11) 10 school = models.CharField(max_length=100) 11 12 # @receiver:用於將接收器鏈接到信號的裝飾器。經過傳入使用信號(或信號列表)和鏈接的關鍵字參數; 13 # sender:發送者 ; instance:調用save的實例 ; created:是不是新建立的; 14 # 接收User的save信號; 15 @receiver(post_save,sender=User) 16 def handler_user_extension(sender,instance,created,**kwargs): 17 if created: 18 UserExtension.objects.create(user=instance) 19 else: 20 instance.extension.save()
1 from django.shortcuts import render 2 from django.http import HttpResponse 3 from django.contrib.auth import authenticate 4 from .models import UserExtension 5 from django.contrib.auth.models import User 6 7 # 自定義驗證號碼及密碼; 8 def my_authenticate(telephone,password): 9 user = User.objects.filter(extension__telephone=telephone).first() 10 if user: 11 is_correct = user.check_password(password) 12 if is_correct: 13 return user 14 else: 15 return None 16 else: 17 return None 18 19 def one_view(request): 20 # 建立用戶,使用外鍵反向引用添加telephone; 21 # user = User.objects.create_user(username='three',password='111111',email='three@123.com') 22 # user.extension.telephone = '18988889999' 23 # user.save() 24 # 進行驗證; 25 telephone = request.GET.get('telephone') 26 password = request.GET.get('password') 27 user = my_authenticate(telephone,password) 28 if user: 29 print('%s:驗證成功'% user.username) 30 else: 31 print('用戶驗證失敗!') 32 return HttpResponse('success')
定義一個 UserExtension的模型 與 User模型 進行一對一的綁定,之後新增的字段,就添加到 UserExtension 上。建立一個接受保存模型的信號處理方法,只要 User 調用了 save 方法,就會建立一個 UserExtension 和 User 進行綁定。
登陸、註銷和登陸限制
登陸用戶:
1 from django.contrib.auth import login 2 3 def my_login(request): 4 if request.method == 'GET': 5 return render(request,'login.html') 6 else: 7 form = LoginForm(request.POST) 8 if form.is_valid(): 9 telephone = form.cleaned_data.get('telephone') 10 password = form.cleaned_data.get('password') 11 remember = form.cleaned_data.get('remember') 12 user = my_authenticate(telephone=telephone,password=password) 13 if user and user.is_active: 14 # 判斷經過時登陸成功,會生成session數據;再判斷是否記住數據; 15 login(request,user) 16 if remember: 17 request.session.set_expiry(None) 18 else: 19 request.session.set_expiry(0) 20 # 定義獲取next時的跳轉頁面 21 next_url = request.GET.get('next') 22 if next_url: 23 return redirect(next_url) 24 else: 25 return HttpResponse('登陸成功') 26 else: 27 return HttpResponse('手機號或密碼錯誤!') 28 else: 29 print(form.errors) 30 return redirect(reverse('login'))
1 <!--login.html--> 2 <tr> 3 <td> 4 <label for=""> 5 <input type="checkbox" name="remember" value="1">記住密碼 6 </label> 7 </td> 8 </tr>
註銷用戶:
1 from django.contrib.auth import logout 2 3 # 註銷用戶 4 def my_logout(request): 5 logout(request) 6 return HttpResponse('退出登陸')
登陸限制:
1 from django.contrib.auth.decorators import login_required 2 3 # 登陸限制,驗證失敗是會跳轉到‘/login/’的url頁面; 4 @login_required(login_url='/login/') 5 def profile(request): 6 return HttpResponse('我的中心,登陸才能查看!')