[TOC]css
在前面的博客中已經學會了給視圖函數加裝飾器來判斷是用戶是否登陸,把沒有登陸的用戶請求跳轉到登陸頁面。咱們經過給幾個特定視圖函數加裝飾器實現了這個需求。可是之後添加的視圖函數可能也須要加上裝飾器,這樣是否是稍微有點繁瑣。
他就像至關於django的門戶,通俗一點就是阻止你進門的保安,須要驗證。
只要是全局相關的功能你都應該考慮使用django中間件來幫你完成html
全局用戶身份校驗 全局用戶訪問頻率校驗 用戶訪問黑名單 用戶訪問白名單
什麼是中間件:python
中間件是一個用來處理Django的請求和響應的框架級別的鉤子。它是一個輕量、低級別的插件系統,用於在全局範圍內改變Django的輸入和輸出。每一箇中間件組件都負責作一些特定的功能。
中間件是幫助咱們在視圖函數執行以前和執行以後均可以作一些額外的操做,它本質上就是一個自定義類,類中定義了幾個方法,Django框架會在請求的特定的時間去執行這些方法。
注意:jquery
可是因爲其影響的是全局,因此須要謹慎使用,使用不當會影響性能。
只要之後用django開發業務 設計到全局相關的功能 你就考慮用中間件ajax
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
中間件能夠定義六個方法,分別是:(主要的是process_request和process_response)django
class SessionMiddleware(MiddlewareMixin): def process_request(self, request): def process_response(self, request, response): class CsrfViewMiddleware(MiddlewareMixin): def process_request(self, request): def process_view(self, request, callback, callback_args, callback_kwargs): def process_response(self, request, response): class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request):
以上方法的返回值能夠是None或一個HttpResponse對象,若是是None,則繼續按照django定義的規則向後繼續執行,若是是HttpResponse對象,則直接將該對象返回給用戶
請求來的時候會按照配置文件中註冊的中間從上往下的順序依次執行每個中間件裏的process_request方法,若是沒有直接跳過執行下一個同級別返回,並不會所有執行process_resquest
process_request有一個參數,就是request,這個request和視圖函數中的request是同樣的 因爲request對象是同樣的,因此咱們能夠對request對象進行一系列的操做,包括request.變量名=變量值,這樣的操做,咱們能夠在後續的視圖函數中經過相同的方式便可獲取到咱們在中間件中設置的值。
它的返回值能夠是None也能夠是HttpResponse對象。返回值是None的話,按正常流程繼續走,交給下一個中間件處理,若是是HttpResponse對象,Django將不執行視圖函數,而將相應對象返回給瀏覽器。
代碼:bootstrap
相應走的時候會按照配置文件中註冊的中間件從下往上的順序依次執行每個中間件裏面的process_response方法,該方法必需要有兩個形參,而且須要將形參respondse返回 若是你內部本身返回了HttpResponse對象 會將返回給用戶瀏覽器的內容替換成你本身的
路人匹配成功執行視圖函數以前觸發
process_view(self, request, view_func, view_args, view_kwargs) 該方法有四個參數 request是HttpRequest對象。 view_func是Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱做爲字符串。) view_args是將傳遞給視圖的位置參數的列表. view_kwargs是將傳遞給視圖的關鍵字參數的字典。 view_args和view_kwargs都不包含第一個視圖參數(request)。 Django會在調用視圖函數以前調用process_view方法。
它應該返回None或一個HttpResponse對象。 若是返回None,Django將繼續處理這個請求,執行任何其餘中間件的process_view方法,而後在執行相應的視圖。 若是它返回一個HttpResponse對象,那麼將不會執行Django的視圖函數,而是直接在中間件中掉頭,倒敘執行一個個process_response方法,最後返回給瀏覽器
視圖函數返回的對象中必需要有render屬性對應的render方法
視圖函數返回的對象中必需要有render屬性對應的render方法 def index(request): print('我是視圖函數index') def render(): return HttpResponse("你好啊 我是index裏面的render函數") obj = HttpResponse("index") obj.render = render return obj
當視圖函數報錯的時候自動觸發
該方法兩個參數: 一個HttpRequest對象 一個exception是視圖函數異常產生的Exception對象 這個方法只有在視圖函數中出現異常了才執行,它返回的值能夠是一個None也能夠是一個HttpResponse對象。若是是HttpResponse對象,Django將調用模板和中間件中的process_response方法,並返回給瀏覽器,不然將默認處理異常。若是返回一個None,則交給下一個中間件的process_exception方法來處理異常。它的執行順序也是按照中間件註冊順序的倒序執行。
本質搭建一個跟正常網站如出一轍的頁面 用戶在該頁面上完成轉帳功能 轉帳的請求確實是朝着正常網站的服務端提交 惟一不一樣的在於收款帳戶人不一樣 給用戶書寫form表單 對方帳戶的input沒有name屬性 你本身悄悄提早寫好了一個具備默認的而且是隱藏的具備name屬性的input 模擬釣魚網站
要作一個網站跟他同樣 效果:給用戶轉的錢到釣魚網站的用戶帳上去了 瀏覽器
解決釣魚網站問題:session
form表單如何經過csrf校驗 你只須要在你的form表單內寫一個 {% csrf_token %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <h2>我是正兒八經的網站</h2> <form action="" method="post"> {# {% csrf_token %}#} <p>username:<input type="text" name="username"></p> <p>target_user:<input type="text" name="target_user"></p> <p>money:<input type="text" name="money"></p> <input type="submit"> </form> <button id="d1">發送ajax請求</button> {#{% load static %}#} {#<script src="{% static 'myset.js' %}"></script>#} {#<script>#} {# $('#d1').click(function () {#} {# $.ajax({#} {# url:'',#} {# type:'post',#} {#data:{'username':'jason'},#} {# // 第一種方式 本身手動獲取#} {#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#} {# // 第二種方式 利用模板語法#} {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} {# // 第三種 通用方式 引入外部js文件#} {# data:{'username':'jason'},#} {# success:function (data) {#} {# alert(data)#} {# }#} {# })#} {# })#} {#</script>#} </body> </html>
// 第一種方式 本身手動獲取 {#data:{'username':'jason','csrfmiddlewaretoken':$('input[name="csrfmiddlewaretoken"]').val()},#} // 第二種方式 利用模板語法 {#data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'},#} // 第三種 通用方式 引入外部js文件 官網提供的方式 {% load static %} <script src="{% static 'myset.js' %}"></script> data:{'username':'jason'}
當咱們網站總體都校驗csrf的時候 我想讓某幾個視圖函數不校驗 當咱們網站總體都不校驗csrf的時候 我想讓某幾個視圖函數校驗
給CBV加裝飾器 推薦你使用模塊method_decorator 咱們本身寫的裝飾器和csrf_protect用法一致 惟獨csrf_exempt是一個特例 只能給dispatch方法裝
導入:框架
from django.views.decorators.csrf import csrf_exempt, csrf_protect from django.views import View9 from django.utils.decorators import method_decorator
# @method_decorator(csrf_protect,name='post') # 第二種指名道姓的給類中某個方法裝 # @method_decorator(csrf_exempt,name='post') # csrf_exempt 第二種方式不行 @method_decorator(csrf_exempt,name='dispatch') # 能夠!!! class MyHome(View): # APIView # @method_decorator(csrf_protect) # 第三種 類中全部的方法都裝 # @method_decorator(csrf_exempt) # csrf_exempt 第三種方式能夠 def dispatch(self, request, *args, **kwargs): return super().dispatch(request,*args,**kwargs) def get(self,request): return HttpResponse('get') # @method_decorator(csrf_protect) # 第一種方式 # @method_decorator(csrf_exempt) # csrf_exempt 第一種方式不行 def post(self,request): return HttpResponse('post')
django用戶相關的自帶的功能模塊 auth_user表
createsuperuser
from django.contrib import auth from django.contrib.auth.models import User
User.objects.create() # 密碼是明文 User.objects.createuser() # 基本都用它 User.objects.createsuperuser() # 郵箱要給數據
auth.authenticate(username=username,password=password) # 用戶名和密碼兩個一個都不能少 # 該方法當用戶名和密碼正確的時候返回的用戶對象 不正確返回None
auth.login(request,user_obj) # 這一句執行以後 request.user獲取當前登陸的用戶對象
request.user.is_authenticated() # 判斷是否登陸 request.user # 登陸用戶對象
from django.contrib.auth.decorators import login_required # 局部配置 @login_required(login_url='/login/') def xxx(request): return HttpResponse('xxx頁面') # 全局配置 配置文件中寫如下代碼 LOGIN_URL = '/login/' @login_required def xxx(request): return HttpResponse('xxx頁面') # 若是兩個都設置了 那麼優先執行局部配置
request.user.check_password(old_password) # 校驗原密碼是否正確 request.user.set_password(new_password) request.user.save() # 必定要保存
auth.logout(request)
# 2 利用類的繼承 # 1 類的繼承 from django.contrib.auth.models import User,AbstractUser # Create your models here. class Userinfo(AbstractUser): phone = models.BigIntegerField() avatar = models.FileField() # 擴展的字段 儘可能不要與原先表中的字段衝突 # 2 配置文件 AUTH_USER_MODEL = '應用名.表名'
總結:
django就會將userinfo表來替換auth_user表 而且以前auth模塊全部的功能不變 參照的也是userinfo表