python å ¨æ å¼åï¼Day87(ajaxç»å½ç¤ºä¾,CSRFè·¨ç«è¯·æ±ä¼ªé ,Djangoçä¸é´ä»¶,èªå®ä¹å页)...
python å ¨æ å¼åï¼Day87(ajaxç»å½ç¤ºä¾,CSRFè·¨ç«è¯·æ±ä¼ªé ,Djangoçä¸é´ä»¶,èªå®ä¹å页)
ä¸ãajaxç»å½ç¤ºä¾
æ°å»ºé¡¹ç®login_ajax
ä¿®æ¹urls.pyï¼å¢å è·¯å¾
from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('index/', views.index), ]
ä¿®æ¹settings.pyï¼æå®static
STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )
ä¿®æ¹views.pyï¼å¢å è§å¾å½æ°
from django.shortcuts import render, HttpResponse, redirect import json # Create your views here. def index(request): return HttpResponse('this is index') def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") ret = {"status": 0, 'url': ''} if user == "xiao" and pwd == "123": ret['status'] = 1 ret['url'] = '/index/' return HttpResponse(json.dumps(ret)) return render(request, "login.html")
å¨staticç®å½ä¸å建cssï¼æ°å»ºsignin.css
body { padding-top: 40px; padding-bottom: 40px; background-color: #eee; } .form-signin { max-width: 330px; padding: 15px; margin: 0 auto; } .form-signin .form-signin-heading, .form-signin .checkbox { margin-bottom: 10px; } .form-signin .checkbox { font-weight: normal; } .form-signin .form-control { position: relative; height: auto; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; padding: 10px; font-size: 16px; } .form-signin .form-control:focus { z-index: 2; } .form-signin input[type="email"] { margin-bottom: -1px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .form-signin input[type="password"] { margin-bottom: 10px; border-top-left-radius: 0; border-top-right-radius: 0; }
å建login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ç»å½</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/signin.css"> </head> <body> <div class="container"> <form class="form-signin"> {% csrf_token %} <h2 class="form-signin-heading">请ç»å½</h2> <label for="inputUser" class="sr-only">ç¨æ·å</label> <input type="text" id="inputUser" class="form-control" placeholder="ç¨æ·å" required="" autofocus="" name="user"> <label for="inputPassword" class="sr-only">å¯ç </label> <input type="password" id="inputPassword" class="form-control" placeholder="å¯ç " required="" name="pwd"> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> è®°ä½æ </label> </div> <input class="btn btn-lg btn-primary btn-block" id="login" value="ç»é"> </form> </div> <!-- /container --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> $('#login').click(function () { $.ajax({ url: '/login/', type: 'post', data: { csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), user: $('[name="user"]').val(), pwd: $('[name="pwd"]').val() }, success: function (data) { data = JSON.parse(data); if (data.status) { //跳转æå®é¡µé¢ window.location = data.url } else { alert('ç»é失败') } } }) }) </script> </body> </html>
访é®ç»å½é¡µé¢ï¼http://127.0.0.1:8000/login/
é误æ¶ï¼æ示ç»å½å¤±è´¥
è¾å ¥æ£ç¡®çç¨æ·ååå¯ç ï¼è·³è½¬é¦é¡µ
äºãCSRFè·¨ç«è¯·æ±ä¼ªé
æ¹å¼ä¸
å° csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val() æ¾å¨POSTç请æ±ä½ä¸ã
示ä¾ä¸å°±æ¯ä½¿ç¨çè¿ç§æ¹å¼ã
æ¹å¼äº
ç»ajaxç请å¢å X-CSRFTokenç请æ±å¤´ï¼å¯¹åºçå¼åªè½æ¯cookieä¸çcsrftokençå¼ã
æ以æ们è¦ä»cookieä¸æåcsrftokençå¼ï¼jQueryä¸è½å»cookieï¼æ们使ç¨jquery.cookieçæ件ãç¹å»ä¸è½½jquer.cookieæ件ã
HTMLä¸å¯¼å ¥jquery.cookie.jsã
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ç»å½</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/signin.css"> </head> <body> <div class="container"> <form class="form-signin"> {% csrf_token %} <h2 class="form-signin-heading">请ç»å½</h2> <label for="inputUser" class="sr-only">ç¨æ·å</label> <input type="text" id="inputUser" class="form-control" placeholder="ç¨æ·å" required="" autofocus="" name="user"> <label for="inputPassword" class="sr-only">å¯ç </label> <input type="password" id="inputPassword" class="form-control" placeholder="å¯ç " required="" name="pwd"> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> è®°ä½æ </label> </div> <input class="btn btn-lg btn-primary btn-block" id="login" value="ç»é"> </form> </div> <!-- /container --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> {#å¿ é¡»å å¼å ¥jqueryï¼åå¼å ¥cookie#} <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> <script> $('#login').click(function () { $.ajax({ url: '/login/', type: 'post', //å¢å X-CSRFTokenç请æ±å¤´ headers:{ "X-CSRFToken":$.cookie('csrftoken') }, data: { //csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), user: $('[name="user"]').val(), pwd: $('[name="pwd"]').val() }, success: function (data) { data = JSON.parse(data); if (data.status) { //跳转æå®é¡µé¢ window.location = data.url; } else { alert('ç»é失败'); } } }) }) </script> </body> </html>
å·æ°é¡µé¢
æ¥çconsoleï¼è½å¾å°cookie为csrftokençå¼
å次ç»å½
åépostæ°æ®æ¶ï¼ä¼åéX-CSRFTokenç请æ±å¤´
æ¹å¼ä¸
使ç¨$.ajaxSetup()ç»å ¨å±çajaxæ·»å é»è®¤åæ°ã
å¯ä»¥æç §æ¹å¼ä¸è®¾ç½®dataï¼ä¹å¯ä»¥æç §æ¹å¼äºè®¾ç½®è¯·æ±å¤´ã
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ç»å½</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/signin.css"> </head> <body> <div class="container"> <form class="form-signin"> {% csrf_token %} <h2 class="form-signin-heading">请ç»å½</h2> <label for="inputUser" class="sr-only">ç¨æ·å</label> <input type="text" id="inputUser" class="form-control" placeholder="ç¨æ·å" required="" autofocus="" name="user"> <label for="inputPassword" class="sr-only">å¯ç </label> <input type="password" id="inputPassword" class="form-control" placeholder="å¯ç " required="" name="pwd"> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> è®°ä½æ </label> </div> <input class="btn btn-lg btn-primary btn-block" id="login" value="ç»é"> </form> </div> <!-- /container --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> {#å¿ é¡»å å¼å ¥jqueryï¼åå¼å ¥cookie#} <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> <script> //æ¹å¼ä¸è®¾ç½®data {#$.ajaxSetup({#} {# data: {#} {# csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),#} {# }#} {# });#} //æ¹å¼äºè®¾ç½®è¯·æ±å¤´ $.ajaxSetup({ headers: {"X-CSRFToken": $.cookie('csrftoken')}, }); $('#login').click(function () { $.ajax({ url: '/login/', type: 'post', //å¢å X-CSRFTokenç请æ±å¤´ headers:{ "X-CSRFToken":$.cookie('csrftoken') }, data: { user: $('[name="user"]').val(), pwd: $('[name="pwd"]').val() }, success: function (data) { data = JSON.parse(data); if (data.status) { //跳转æå®é¡µé¢ window.location = data.url; } else { alert('ç»é失败'); } } }) }) </script> </body> </html>
éæ°ç»å½ï¼ææåä¸ï¼
æ¹å¼å
å®æ¹æ¨èæ¹æ³ï¼ç¨å°jquery.cookieæ件ï¼ï¼
function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken')); } } });
login.htmlå®æ´ä»£ç å¦ä¸ï¼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ç»å½</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/signin.css"> </head> <body> <div class="container"> <form class="form-signin"> {% csrf_token %} <h2 class="form-signin-heading">请ç»å½</h2> <label for="inputUser" class="sr-only">ç¨æ·å</label> <input type="text" id="inputUser" class="form-control" placeholder="ç¨æ·å" required="" autofocus="" name="user"> <label for="inputPassword" class="sr-only">å¯ç </label> <input type="password" id="inputPassword" class="form-control" placeholder="å¯ç " required="" name="pwd"> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> è®°ä½æ </label> </div> <input class="btn btn-lg btn-primary btn-block" id="login" value="ç»é"> </form> </div> <!-- /container --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> {#å¿ é¡»å å¼å ¥jqueryï¼åå¼å ¥cookie#} <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> <script> //ajaxå¨åéä¹åï¼åçheader头ãcsrfSafeMethodæ¯ä¸ä¸ªæ¹æ³åï¼ç¨æ¥è°ç¨ç function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection //è¿äºHTTPæ¹æ³ä¸éè¦CSRFä¿æ¤ // å¹é methodç请æ±æ¨¡å¼ï¼jsæ£åå¹é ç¨test return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } // 为ajax请æ±åcsrf_token $.ajaxSetup({ //beforeSend å¨åæå¡å¨åé请æ±åæ§è¡ä¸äºå¨ä½ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { // å¨è¯·æ±å¤´è®¾ç½®ä¸æ¬¡csrf_token,é¤äºä¸é¢æ£åå¹é å°çä¸å¸¦csrf_tokenï¼å ¶ä»çé½è¦å¸¦ xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken')); } } }); $('#login').click(function () { $.ajax({ url: '/login/', type: 'post', //å¢å X-CSRFTokenç请æ±å¤´ headers:{ "X-CSRFToken":$.cookie('csrftoken') }, data: { user: $('[name="user"]').val(), pwd: $('[name="pwd"]').val() }, success: function (data) { data = JSON.parse(data); if (data.status) { //跳转æå®é¡µé¢ window.location = data.url; } else { alert('ç»é失败'); } } }) }) </script> </body> </html>
å·æ°é¡µé¢ï¼éæ°ç»å½ï¼ææåä¸ï¼
ä¸ãDjangoçä¸é´ä»¶
åæ
æ们å¨åé¢ç课ç¨ä¸å·²ç»å¦ä¼äºç»è§å¾å½æ°å è£ é¥°å¨æ¥å¤ææ¯ç¨æ·æ¯å¦ç»å½ï¼æ没æç»å½çç¨æ·è¯·æ±è·³è½¬å°ç»å½é¡µé¢ãæ们éè¿ç»å 个ç¹å®è§å¾å½æ°å è£ é¥°å¨å®ç°äºè¿ä¸ªéæ±ãä½æ¯ä»¥åæ·»å çè§å¾å½æ°å¯è½ä¹éè¦å ä¸è£ 饰å¨ï¼è¿æ ·æ¯ä¸æ¯ç¨å¾®æç¹ç¹çã
å¦å®ä»å¤©çå 容ä¹åå¢ï¼æ们就å¯ä»¥ç¨æ´éå®çæ¹å¼æ¥å®ç°ç±»ä¼¼ç»ææ请æ±é½åç¸åæä½çåè½äºã
ä»ä¹æ¯ä¸é´ä»¶ï¼
å®æ¹ç说æ³ï¼ä¸é´ä»¶æ¯ä¸ä¸ªç¨æ¥å¤çDjangoç请æ±åååºçæ¡æ¶çº§å«çé©åãå®æ¯ä¸ä¸ªè½»éãä½çº§å«çæ件系ç»ï¼ç¨äºå¨å ¨å±èå´å æ¹åDjangoçè¾å ¥åè¾åºãæ¯ä¸ªä¸é´ä»¶ç»ä»¶é½è´è´£åä¸äºç¹å®çåè½ã
è¾å ¥åè¾åºï¼è¿éæçæ¯è¯·æ±åååº
ä½æ¯ç±äºå ¶å½±åçæ¯å ¨å±ï¼æ以éè¦è°¨æ 使ç¨ï¼ä½¿ç¨ä¸å½ä¼å½±åæ§è½ã
说çç´ç½ä¸ç¹ä¸é´ä»¶æ¯å¸®å©æ们å¨è§å¾å½æ°æ§è¡ä¹ååæ§è¡ä¹åé½å¯ä»¥åä¸äºé¢å¤çæä½ï¼å®æ¬è´¨ä¸å°±æ¯ä¸ä¸ªèªå®ä¹ç±»ï¼ç±»ä¸å®ä¹äºå 个æ¹æ³ï¼Djangoæ¡æ¶ä¼å¨å¤ç请æ±çç¹å®çæ¶é´å»æ§è¡è¿äºæ¹æ³ã
æ们ä¸ç´é½å¨ä½¿ç¨ä¸é´ä»¶ï¼åªæ¯æ²¡æ注æå°èå·²ï¼æå¼Django项ç®çSettings.pyæ件ï¼çå°ä¸å¾çMIDDLEWAREé 置项ã
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', ]
MIDDLEWAREé 置项æ¯ä¸ä¸ªå表ï¼å表ä¸æ¯ä¸ä¸ªä¸ªå符串ï¼è¿äºåç¬¦ä¸²å ¶å®æ¯ä¸ä¸ªä¸ªç±»ï¼ä¹å°±æ¯ä¸ä¸ªä¸ªä¸é´ä»¶ã
æ们ä¹åå·²ç»æ¥è§¦è¿ä¸ä¸ªcsrfç¸å ³çä¸é´ä»¶äºï¼æ们ä¸å¼å§è®©å¤§å®¶æä»æ³¨éæï¼åæ交post请æ±çæ¶åï¼å°±ä¸ä¼è¢«forbiddenäºï¼åæ¥å¦ä¼ä½¿ç¨csrf_tokenä¹åå°±ä¸å注éè¿ä¸ªä¸é´ä»¶äºã
åççä¸é´ä»¶ï¼ä¸è¦å ³éï¼
é£æ¥ä¸æ¥å°±å¦ä¹ ä¸é´ä»¶ä¸çæ¹æ³ä»¥åè¿äºæ¹æ³ä»ä¹æ¶å被æ§è¡ã
ä¿®æ¹settings.pyï¼å¯¼å ¥ä¸ä¸ªcsrfçä¸é´ä»¶
from django.middleware.csrf import CsrfViewMiddleware 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', ]
使ç¨Ctrl+é¼ æ å·¦é®ï¼ç¹å»CsrfViewMiddlewareï¼æ¥çæºç ã
åç°å®ç»§æ¿äºMiddlewareMixinãææä¸é´ä»¶ï¼å¿ 须继æ¿MiddlewareMixin
å°å 个æºç æå ï¼ææå¦ä¸ï¼
å®ä½¿ç¨äº3个æ¹æ³ï¼ä¸é¢ä¼ä¸ä¸è®²è§£
å°ä¸é¢çå¯¼å ¥çCsrfViewMiddlewareå æï¼è¿åsettings.pyçç¶æï¼
èªå®ä¹ä¸é´ä»¶
ä¸é´ä»¶å¯ä»¥å®ä¹äºä¸ªæ¹æ³ï¼åå«æ¯ï¼ï¼ä¸»è¦çæ¯process_requeståprocess_responseï¼
- process_request(self,request)
- process_view(self, request, view_func, view_args, view_kwargs)
- process_template_response(self,request,response)
- process_exception(self, request, exception)
- process_response(self, request, response)
以ä¸æ¹æ³çè¿åå¼å¯ä»¥æ¯Noneæä¸ä¸ªHttpResponse对象ï¼å¦ææ¯Noneï¼å继ç»æç §djangoå®ä¹çè§ååå继ç»æ§è¡ï¼å¦ææ¯HttpResponse对象ï¼åç´æ¥å°è¯¥å¯¹è±¡è¿åç»ç¨æ·ã
èªå®ä¹ä¸ä¸ªä¸é´ä»¶ç¤ºä¾
举ä¾1ï¼
è¿æ¯æ¿ä¸é¢çlogin_ajax项ç®æ¥æµè¯
å¨app01ç®å½ä¸å建æ件middlewares.pyï¼è¿ä¸ªååæ æè°
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): # ä¸é´ä»¶å¿ é¡»è¦ç»§æ¿MiddlewareMixin # æ¹å¼åå¿ é¡»æ¯ä¸é¢å®ä¹ç5个 # requestæ¯è§å¾å½æ°ä¸çrequestè¦æ©ä¸æ¥ def process_request(self, request): print("MD1éé¢ç process_request") # response æ¯å½¢åï¼ååæ æè° def process_response(self, request, response): print("MD1éé¢ç process_response") return response
注æï¼ä¸é¢å®ä¹ç2个æ¹æ³ï¼æ²¡æreturnï¼é£ä¹é»è®¤è¿åå¼ä¸ºNone
ä¿®æ¹settings.pyéé¢çMIDDLEWAREï¼æåä¸ä¸ªå ç´ æ·»å
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', # è¿éæçæ¯app01ç®å½ä¸çmiddlewares模åï¼éé¢çMD1ç±» 'app01.middlewares.MD1' ]
ä¿®æ¹views.pyéé¢çindexè§å¾å½æ°
def index(request): print("index") return HttpResponse('this is index')
ç½é¡µè®¿é®index页é¢ï¼
æ¥çpycharmæ§å¶å°è¾åºï¼
MD1éé¢ç process_request [20/Jul/2018 09:38:18] "GET /index/ HTTP/1.1" 200 13 index MD1éé¢ç process_response
å¯ä»¥çåºï¼å®çæ§è¡é¡ºåºå¦ä¸ï¼
MD1éé¢ç process_request --> indexè§å¾å½æ° --> MD1éé¢ç process_response
process_request
process_requestæä¸ä¸ªåæ°ï¼å°±æ¯requestï¼è¿ä¸ªrequeståè§å¾å½æ°ä¸çrequestæ¯ä¸æ ·çã
å®çè¿åå¼å¯ä»¥æ¯Noneä¹å¯ä»¥æ¯HttpResponse对象ãè¿åå¼æ¯Noneçè¯ï¼ææ£å¸¸æµç¨ç»§ç»èµ°ï¼äº¤ç»ä¸ä¸ä¸ªä¸é´ä»¶å¤çï¼å¦ææ¯HttpResponse对象ï¼Djangoå°ä¸æ§è¡è§å¾å½æ°ï¼èå°ååºå¯¹è±¡è¿åç»æµè§å¨ã
æ们æ¥ççå¤ä¸ªä¸é´ä»¶æ¶ï¼Djangoæ¯å¦ä½æ§è¡å ¶ä¸çprocess_requestæ¹æ³çã
举ä¾ï¼
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request")
å¨settings.pyçMIDDLEWAREé 置项ä¸æ³¨åä¸è¿°ä¸¤ä¸ªèªå®ä¹ä¸é´ä»¶ï¼
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', # è¿éæçæ¯app01ç®å½ä¸çmiddlewares模åï¼éé¢çMD1ç±» 'app01.middlewares.MD1', # èªå®ä¹ä¸é´ä»¶MD1 'app01.middlewares.MD2' # èªå®ä¹ä¸é´ä»¶MD2 ]
ä¿®æ¹views.pyä¸çindexè§å¾å½æ°
def index(request): print("app01 ä¸ç indexè§å¾") return HttpResponse('this is index')
å·æ°é¡µé¢ï¼æ¥çPycharmæ§å¶å°è¾åºï¼
MD1éé¢ç process_request
MD2éé¢ç process_request
app01 ä¸ç indexè§å¾
æMD1åMD2çä½ç½®è°æ¢ä¸ä¸ï¼ä¿®æ¹settings.pyçMIDDLEWAREé 置项
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', 'app01.middlewares.MD2', # èªå®ä¹ä¸é´ä»¶MD2 'app01.middlewares.MD1', # èªå®ä¹ä¸é´ä»¶MD1 ]
å·æ°é¡µé¢ï¼ä¼åç°ç»ç«¯ä¸æå°çå 容å¦ä¸ï¼
MD2éé¢ç process_request [20/Jul/2018 09:49:18] "GET /index/ HTTP/1.1" 200 13 MD1éé¢ç process_request app01 ä¸ç indexè§å¾
çç»ææ们ç¥éï¼è§å¾å½æ°è¿æ¯æåæ§è¡çï¼MD2æ¯MD1å æ§è¡èªå·±çprocess_requestæ¹æ³ã
å¨æå°ä¸ä¸ä¸¤ä¸ªèªå®ä¹ä¸é´ä»¶ä¸process_requestæ¹æ³ä¸çrequeståæ°ï¼ä¼åç°å®ä»¬æ¯åä¸ä¸ªå¯¹è±¡ã
ç±æ¤æ»ç»ä¸ä¸ï¼
- ä¸é´ä»¶çprocess_requestæ¹æ³æ¯å¨æ§è¡è§å¾å½æ°ä¹åæ§è¡çã
- å½é ç½®å¤ä¸ªä¸é´ä»¶æ¶ï¼ä¼æç §MIDDLEWAREä¸ç注å顺åºï¼ä¹å°±æ¯å表çç´¢å¼å¼ï¼ä»åå°åä¾æ¬¡æ§è¡çã
- ä¸åä¸é´ä»¶ä¹é´ä¼ éçrequesté½æ¯åä¸ä¸ªå¯¹è±¡
process_response
å®æ两个åæ°ï¼ä¸ä¸ªæ¯requestï¼ä¸ä¸ªæ¯responseï¼requestå°±æ¯ä¸è¿°ä¾åä¸ä¸æ ·ç对象ï¼responseæ¯è§å¾å½æ°è¿åçHttpResponse对象ã该æ¹æ³çè¿åå¼ä¹å¿ é¡»æ¯HttpResponse对象ã
ç»ä¸è¿°çM1åM2å ä¸process_responseæ¹æ³ï¼
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") def process_response(self, request, response): print("MD1éé¢ç process_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request") def process_response(self, request, response): print("MD2éé¢ç process_response") return response
å·æ°é¡µé¢ï¼æ¥çPycharmæ§å¶å°è¾åºï¼
MD2éé¢ç process_request MD1éé¢ç process_request app01 ä¸ç indexè§å¾ MD1éé¢ç process_response MD2éé¢ç process_response [20/Jul/2018 09:51:57] "GET /index/ HTTP/1.1" 200 13
çç»æå¯ç¥ï¼
process_responseæ¹æ³æ¯å¨è§å¾å½æ°ä¹åæ§è¡çï¼å¹¶ä¸é¡ºåºæ¯MD1æ¯MD2å æ§è¡ã(æ¤æ¶settings.pyä¸ MD2æ¯MD1å 注å)
å¤ä¸ªä¸é´ä»¶ä¸çprocess_responseæ¹æ³æ¯æç §MIDDLEWAREä¸ç注å顺åºååºæ§è¡çï¼ä¹å°±æ¯è¯´ç¬¬ä¸ä¸ªä¸é´ä»¶çprocess_requestæ¹æ³é¦å æ§è¡ï¼èå®çprocess_responseæ¹æ³æåæ§è¡ï¼æåä¸ä¸ªä¸é´ä»¶çprocess_requestæ¹æ³æåä¸ä¸ªæ§è¡ï¼å®çprocess_responseæ¹æ³æ¯æå æ§è¡ã
process_view
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æ¹æ³å¹¶å°åºç¨å°è¯¥HttpResponse并è¿åç»æã
ç»MD1åMD2æ·»å process_viewæ¹æ³:
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") def process_response(self, request, response): print("MD1éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 ä¸çprocess_view") # view_func.__name__ 表示æ¥çå½æ°å print(view_func, view_func.__name__) class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request") pass def process_response(self, request, response): print("MD2éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 ä¸çprocess_view") print(view_func, view_func.__name__)
å·æ°é¡µé¢ï¼æ¥çPycharmæ§å¶å°è¾åºï¼
MD2éé¢ç process_request [20/Jul/2018 09:56:24] "GET /index/ HTTP/1.1" 200 13 MD1éé¢ç process_request -------------------------------------------------------------------------------- MD2 ä¸çprocess_view <function index at 0x000002CEAA9C9E18> index -------------------------------------------------------------------------------- MD1 ä¸çprocess_view <function index at 0x000002CEAA9C9E18> index app01 ä¸ç indexè§å¾ MD1éé¢ç process_response MD2éé¢ç process_response
process_viewæ¹æ³æ¯å¨process_requestä¹åï¼è§å¾å½æ°ä¹åæ§è¡çï¼æ§è¡é¡ºåºæç §MIDDLEWAREä¸ç注å顺åºä»åå°å顺åºæ§è¡ç
process_exception
process_exception(self, request, exception)
该æ¹æ³ä¸¤ä¸ªåæ°:
ä¸ä¸ªHttpRequest对象
ä¸ä¸ªexceptionæ¯è§å¾å½æ°å¼å¸¸äº§ççException对象ã
è¿ä¸ªæ¹æ³åªæå¨è§å¾å½æ°ä¸åºç°å¼å¸¸äºææ§è¡ï¼å®è¿åçå¼å¯ä»¥æ¯ä¸ä¸ªNoneä¹å¯ä»¥æ¯ä¸ä¸ªHttpResponse对象ãå¦ææ¯HttpResponse对象ï¼Djangoå°è°ç¨æ¨¡æ¿åä¸é´ä»¶ä¸çprocess_responseæ¹æ³ï¼å¹¶è¿åç»æµè§å¨ï¼å¦åå°é»è®¤å¤çå¼å¸¸ãå¦æè¿åä¸ä¸ªNoneï¼å交ç»ä¸ä¸ä¸ªä¸é´ä»¶çprocess_exceptionæ¹æ³æ¥å¤çå¼å¸¸ãå®çæ§è¡é¡ºåºä¹æ¯æç §ä¸é´ä»¶æ³¨å顺åºçååºæ§è¡ã
ç»MD1åMD2æ·»å ä¸è¿ä¸ªæ¹æ³ï¼
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") def process_response(self, request, response): print("MD1éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 ä¸çprocess_exception") class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request") def process_response(self, request, response): print("MD2éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 ä¸çprocess_exception")
å¦æè§å¾å½æ°ä¸æ å¼å¸¸ï¼process_exceptionæ¹æ³ä¸æ§è¡ã
æ³åæ³ï¼å¨è§å¾å½æ°ä¸æåºä¸ä¸ªå¼å¸¸ï¼
ä¿®æ¹views.pyä¸çindexè§å¾å½æ°ï¼raise表示主å¨æ¥é
def index(request): print("app01 ä¸ç indexè§å¾") raise ValueError("åµåµ") return HttpResponse("O98K")
å¨MD1çprocess_exceptionä¸è¿åä¸ä¸ªååºå¯¹è±¡ï¼
ä¿®æ¹app01ä¸é¢çmiddlewares.pyï¼æ³¨æï¼è¦å¯¼å ¥HttpResponseãå®æ´ä»£ç å¦ä¸ï¼
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render, HttpResponse, redirect class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") def process_response(self, request, response): print("MD1éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 ä¸çprocess_exception") return HttpResponse(str(exception)) # è¿åä¸ä¸ªååºå¯¹è±¡ class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request") def process_response(self, request, response): print("MD2éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 ä¸çprocess_exception")
å·æ°é¡µé¢ï¼ç½é¡µææå¦ä¸ï¼
æ¥çPycharmæ§å¶å°è¾åºï¼
MD2éé¢ç process_request MD1éé¢ç process_request -------------------------------------------------------------------------------- MD2 ä¸çprocess_view <function index at 0x000002A8A993AE18> index -------------------------------------------------------------------------------- MD1 ä¸çprocess_view <function index at 0x000002A8A993AE18> index app01 ä¸ç indexè§å¾ åµåµ MD1 ä¸çprocess_exception MD1éé¢ç process_response MD2éé¢ç process_response [20/Jul/2018 10:03:52] "GET /index/ HTTP/1.1" 200 6
注æï¼è¿é并没ææ§è¡MD2çprocess_exceptionæ¹æ³ï¼å 为MD1ä¸çprocess_exceptionæ¹æ³ç´æ¥è¿åäºä¸ä¸ªååºå¯¹è±¡ã
å 为HTTPæ¯ä¸æ¬¡è¯·æ±ï¼ä¸æ¬¡ååºï¼è¿æ¥å°±æå¼äºãæ以MD2ä¸çprocess_exceptionæ¹æ³æ²¡ææ§è¡ã
process_template_responseï¼ç¨çæ¯è¾å°ï¼
process_template_response(self, request, response)
å®çåæ°ï¼ä¸ä¸ªHttpRequest对象ï¼responseæ¯TemplateResponse对象ï¼ç±è§å¾å½æ°æè ä¸é´ä»¶äº§çï¼ã
process_template_responseæ¯å¨è§å¾å½æ°æ§è¡å®æåç«å³æ§è¡ï¼ä½æ¯å®æä¸ä¸ªåææ¡ä»¶ï¼é£å°±æ¯è§å¾å½æ°è¿åç对象æä¸ä¸ªrender()æ¹æ³ï¼æè 表æ该对象æ¯ä¸ä¸ªTemplateResponse对象æçä»·æ¹æ³ï¼ã
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render, HttpResponse, redirect class MD1(MiddlewareMixin): def process_request(self, request): print("MD1éé¢ç process_request") def process_response(self, request, response): print("MD1éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD1 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD1 ä¸çprocess_exception") return HttpResponse(str(exception)) def process_template_response(self, request, response): print("MD1 ä¸çprocess_template_response") return response class MD2(MiddlewareMixin): def process_request(self, request): print("MD2éé¢ç process_request") pass def process_response(self, request, response): print("MD2éé¢ç process_response") return response def process_view(self, request, view_func, view_args, view_kwargs): print("-" * 80) print("MD2 ä¸çprocess_view") print(view_func, view_func.__name__) def process_exception(self, request, exception): print(exception) print("MD2 ä¸çprocess_exception") def process_template_response(self, request, response): print("MD2 ä¸çprocess_template_response") return response
ä¿®æ¹views.pyä¸çindexè§å¾å½æ°ï¼èªå®ä¹ä¸ä¸ªrenderæ¹æ³ã注æï¼å®ä¸æ¯djangoèªå¸¦çrender
def index(request): print("app01 ä¸ç indexè§å¾") # å®ä¹ä¸ä¸ªrenderæ¹æ³ï¼æ³¨æï¼å®ä¸æ¯djangoèªå¸¦çrender def render(): print("in index/render") return HttpResponse("O98K") rep = HttpResponse("OK") # ç»repåéå¢å ä¸ä¸ªæ¹æ³renderï¼è¿æ¯é¢å对象çç¥è¯ç¹ rep.render = render return rep
å·æ°é¡µé¢ï¼ç½é¡µè¾åºï¼
æ¥çPycharmæ§å¶å°è¾åºï¼
MD2éé¢ç process_request [20/Jul/2018 10:12:52] "GET /index/ HTTP/1.1" 200 4 MD1éé¢ç process_request -------------------------------------------------------------------------------- MD2 ä¸çprocess_view <function index at 0x000001661AC4AE18> index -------------------------------------------------------------------------------- MD1 ä¸çprocess_view <function index at 0x000001661AC4AE18> index app01 ä¸ç indexè§å¾ MD1 ä¸çprocess_template_response MD2 ä¸çprocess_template_response in index/render MD1éé¢ç process_response MD2éé¢ç process_response
ä»ç»æçåºï¼
è§å¾å½æ°æ§è¡å®ä¹åï¼ç«å³æ§è¡äºä¸é´ä»¶çprocess_template_responseæ¹æ³ï¼é¡ºåºæ¯ååºï¼å æ§è¡MD1çï¼å¨æ§è¡MD2çï¼æ¥çæ§è¡äºè§å¾å½æ°è¿åçHttpResponse对象çrenderæ¹æ³ï¼è¿åäºä¸ä¸ªæ°çHttpResponse对象ï¼æ¥çæ§è¡ä¸é´ä»¶process_responseæ¹æ³ã
ä¸é´ä»¶çæ§è¡æµç¨
ä¸ä¸é¨åï¼æ们äºè§£äºä¸é´ä»¶ä¸ç5个æ¹æ³ï¼å®ä»¬çåæ°ãè¿åå¼ä»¥åä»ä¹æ¶åæ§è¡ï¼ç°å¨æ»ç»ä¸ä¸ä¸é´ä»¶çæ§è¡æµç¨ã
请æ±å°è¾¾ä¸é´ä»¶ä¹åï¼å æç §æ£åºæ§è¡æ¯ä¸ªæ³¨åä¸é´ä»¶çprocess_requesæ¹æ³ï¼process_requestæ¹æ³è¿åçå¼æ¯Noneï¼å°±ä¾æ¬¡æ§è¡ï¼å¦æè¿åçå¼æ¯HttpResponse对象ï¼ä¸åæ§è¡åé¢çprocess_requestæ¹æ³ï¼èæ¯æ§è¡å½å对åºä¸é´ä»¶çprocess_responseæ¹æ³ï¼å°HttpResponse对象è¿åç»æµè§å¨ãä¹å°±æ¯è¯´ï¼å¦æMIDDLEWAREä¸æ³¨åäº6个ä¸é´ä»¶ï¼æ§è¡è¿ç¨ä¸ï¼ç¬¬3个ä¸é´ä»¶è¿åäºä¸ä¸ªHttpResponse对象ï¼é£ä¹ç¬¬4,5,6ä¸é´ä»¶çprocess_requeståprocess_responseæ¹æ³é½ä¸æ§è¡ï¼é¡ºåºæ§è¡3,2,1ä¸é´ä»¶çprocess_responseæ¹æ³ã
process_requestæ¹æ³é½æ§è¡å®åï¼å¹é è·¯ç±ï¼æ¾å°è¦æ§è¡çè§å¾å½æ°ï¼å ä¸æ§è¡è§å¾å½æ°ï¼å æ§è¡ä¸é´ä»¶ä¸çprocess_viewæ¹æ³ï¼process_viewæ¹æ³è¿åNoneï¼ç»§ç»æ顺åºæ§è¡ï¼ææprocess_viewæ¹æ³æ§è¡å®åæ§è¡è§å¾å½æ°ãåå¦ä¸é´ä»¶3 çprocess_viewæ¹æ³è¿åäºHttpResponse对象ï¼å4,5,6çprocess_view以åè§å¾å½æ°é½ä¸æ§è¡ï¼ç´æ¥ä»æåä¸ä¸ªä¸é´ä»¶ï¼ä¹å°±æ¯ä¸é´ä»¶6çprocess_responseæ¹æ³å¼å§ååºæ§è¡ã
process_template_responseåprocess_exception两个æ¹æ³ç触åæ¯ææ¡ä»¶çï¼æ§è¡é¡ºåºä¹æ¯ååºãæ»ç»ææçæ§è¡æµç¨å¦ä¸ï¼
æ»ç»ï¼
process_requestï¼ 1. æ¯å¨è§å¾æ§è¡åæ§è¡ç 2. å®ç顺åºæ¯ä»ä¸å¾ä¸ 3. è¿åå¼æ¯None,继ç»å¾åæ§è¡ 4. è¿åå¼æ¯HttpResponseç对象ï¼æ§è¡å¯¹åºä¸é´ä»¶çprocess_responseæ¹æ³ ï¼æ¥çå¾ä¸ï¼è¿åç»æµè§å¨ process_response: 1. æ¯å¨è§å¾æ§è¡åæ§è¡ç 2. å®ç顺åºæ¯ä»ä¸å¾ä¸ 3. è¿åå¿ é¡»æ¯HttpResponseç对象ï¼ç»§ç»å¾ä¸æ§è¡ process_viewï¼ 1. æ¯å¨è§å¾æ§è¡åæ§è¡çï¼process_requestä¹å 2. å®ç顺åºæ¯ä»ä¸å¾ä¸ 3. è¿åå¼æ¯None,继ç»å¾åæ§è¡ 4. è¿åå¼æ¯HttpResponseç对象ï¼æ§è¡æåä¸ä¸ªä¸é´ä»¶çprocess_responseæ¹æ³ ï¼æ¥çå¾ä¸ï¼è¿åç»æµè§å¨ï¼è§å¾ä¸èµ°äº process_exceptionï¼ 1. æ¥éäºææ§è¡ 2. å¨è§å¾å½æ°ä¹åï¼process_responseä¹å 3. å®ç顺åºæ¯ä»ä¸å¾ä¸ 4. è¿åå¼æ¯HttpResponseç对象ï¼æ§è¡æåä¸ä¸ªä¸é´ä»¶çprocess_responseæ¹æ³ ï¼æ¥çå¾ä¸ï¼è¿åç»æµè§å¨ process_template_responseï¼ 1. è§å¾è¿åç对象ærenderæ¹æ³ ææ§è¡ 2. å¨è§å¾å½æ°ä¹åï¼process_responseä¹å 3. å®ç顺åºæ¯ä»ä¸å¾ä¸ 4. è¿åå¼æ¯HttpResponseç对象ã 5. æ§è¡å®ææçä¸é´ä»¶çprocess_template_responseä¹åï¼ ææ§è¡å¯¹è±¡.render()å¾å°ä¸ä¸ªæ°çHttpResponseç对象ï¼æ§è¡å¾äº¤ç»process_response继ç»
ä¸é´ä»¶çç»å½éªè¯
python manage.py makemigrations
python manage.py migrate
ä¿®æ¹urls.pyï¼å¢å è·¯å¾
urlpatterns = [ path('admin/', admin.site.urls), path('login/', views.login), path('logout/', views.logout), path('index/', views.index), path('home/', views.home), ]
ä¿®æ¹views.py
from django.shortcuts import render, HttpResponse, redirect from django.contrib import auth import json # Create your views here. def login(request): if request.method == "POST": user = request.POST.get("user") pwd = request.POST.get("pwd") ret = {"status": 0, 'url': ''} if user == "xiao" and pwd == "123": # 设置session request.session["user"] = user ret['status'] = 1 # 跳转å°indexé¡µé¢ ret['url'] = '/index/' return HttpResponse(json.dumps(ret)) return render(request, "login.html") def logout(request): # 注é auth.logout(request) return redirect("/login/") def index(request): return HttpResponse('this is index <a href="/logout/">注é</a>') def home(request): return HttpResponse('this is home')
ä¿®æ¹app01ä¸é¢çmiddlewares.py
from django.utils.deprecation import MiddlewareMixin from django.shortcuts import render, redirect, HttpResponse class AuthMD(MiddlewareMixin): # éªè¯ç»å½ white_list = ['/login/', ] # ç½åå black_list = ['/black/', ] # é»åå ret = {"status": 0, 'url': '', 'msg': ''} # é»è®¤ç¶æ def process_request(self, request): # 请æ±ä¹å request_url = request.path_info # è·å请æ±è·¯å¾ # get_full_path()表示带åæ°çè·¯å¾ print(request.path_info, request.get_full_path()) # é»ååçç½åéå¶è®¿é® if request_url in self.black_list: self.ret['msg'] = "è¿æ¯éæ³è¯·æ±" self.ret['url'] = "/login/" # ç½ååçç½åæè ç»éç¨æ·ä¸åéå¶ # å¤ææ¯å¦å¨ç½ååå æè å·²ç»æäºsession(表示已ç»ç»å½äº) elif request_url in self.white_list or request.session.get("user"): return None else: self.ret['msg'] = "请ç»å½å,å访é®!" self.ret['url'] = "/login/" # é误页é¢æ示 return render(request, "jump.html", self.ret)
ä¿®æ¹settings.pyçMIDDLEWAREé 置项
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', 'app01.middlewares.AuthMD', # èªå®ä¹ä¸é´ä»¶AuthMD ]
æ°å»ºæ件jump.htmlï¼ç¨æ¥åä¸é´ä»¶ä¸éè¿æ¶ï¼js跳转
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <link rel="stylesheet" href="http://mishengqiang.com/sweetalert/css/sweetalert.css"> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="http://mishengqiang.com/sweetalert/js/sweetalert-dev.js"></script> <div> {#è·åé误信æ¯#} <input type="hidden" id="msg" value="{{ msg }}"> <input type="hidden" id="url" value="{{ url }}"> </div> <script> $(function () { var msg = $("#msg").val(); var url = $("#url").val(); console.log(msg); console.log(url); if (msg.length > 0) { //å¤ææ¯å¦æéè¯¯ä¿¡æ¯ swal({ title: msg, text: "2ç§åèªå¨å ³éã", type: 'error', timer: 2000, showConfirmButton: false }, function () { window.location.href = url; //跳转æå®url }); } }) </script> </body> </html>
login.htmlï¼è¿ä¸ªè¿æ¯ç¨ç第4ç§csrf
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ç»å½</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/signin.css"> </head> <body> <div class="container"> <form class="form-signin"> {% csrf_token %} <h2 class="form-signin-heading">请ç»å½</h2> <label for="inputUser" class="sr-only">ç¨æ·å</label> <input type="text" id="inputUser" class="form-control" placeholder="ç¨æ·å" required="" autofocus="" name="user"> <label for="inputPassword" class="sr-only">å¯ç </label> <input type="password" id="inputPassword" class="form-control" placeholder="å¯ç " required="" name="pwd"> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> è®°ä½æ </label> </div> <input class="btn btn-lg btn-primary btn-block" id="login" value="ç»é"> </form> </div> <!-- /container --> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> {#å¿ é¡»å å¼å ¥jqueryï¼åå¼å ¥cookie#} <script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> {#sweetalertæ件#} <link rel="stylesheet" href="http://mishengqiang.com/sweetalert/css/sweetalert.css"> <script src="http://mishengqiang.com/sweetalert/js/sweetalert-dev.js"></script> <script> //ajaxå¨åéä¹åï¼åçheader头ãcsrfSafeMethodæ¯ä¸ä¸ªæ¹æ³åï¼ç¨æ¥è°ç¨ç function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection //è¿äºHTTPæ¹æ³ä¸éè¦CSRFä¿æ¤ // å¹é methodç请æ±æ¨¡å¼ï¼jsæ£åå¹é ç¨test return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } // 为ajax请æ±åcsrf_token $.ajaxSetup({ //beforeSend å¨åæå¡å¨åé请æ±åæ§è¡ä¸äºå¨ä½ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { // å¨è¯·æ±å¤´è®¾ç½®ä¸æ¬¡csrf_token,é¤äºä¸é¢æ£åå¹é å°çä¸å¸¦csrf_tokenï¼å ¶ä»çé½è¦å¸¦ xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken')); } } }); $('#login').click(function () { $.ajax({ url: '/login/', type: 'post', //å¢å X-CSRFTokenç请æ±å¤´ headers:{ "X-CSRFToken":$.cookie('csrftoken') }, data: { user: $('[name="user"]').val(), pwd: $('[name="pwd"]').val() }, success: function (data) { data = JSON.parse(data); if (data.status) { swal({ title: 'ç»å½æå', type: 'success', //å±ç¤ºæåçå¾ç timer: 500, //延æ¶500æ¯«ç§ showConfirmButton: false //å ³éç¡®è®¤æ¡ }, function () { window.location.href = data.url; //跳转åå°é¦é¡µ }); } else { sweetAlert("ç»å½å¤±è´¥ï¼", data.msg, "error"); } } }) }) </script> </body> </html>
访é®login页é¢ï¼
访é®index页é¢ï¼æ³¨æï¼æ¤æ¶è¿æ²¡æsession
访é®é»åå页é¢
ç»å½é¡µé¢ï¼è¾å ¥æ£ç¡®çç¨æ·ååå¯ç
è¿ä¸ªæ¶åï¼æäºsessinonï¼å¯ä»¥ç´æ¥è®¿é®home
åãèªå®ä¹å页
å页åè½å¨æ¯ä¸ªç½ç«é½æ¯å¿ è¦çï¼djangoèªå¸¦äºå页ç»ä»¶Paginatorï¼å°±å¯ä»¥å®ç°å页åè½ã
é£ä¹ä¸ºä»ä¹è¦èªå®ä¹å页å¢ï¼æ¯å¦flaskæ¡æ¶æ¯æ²¡æå页ç»ä»¶çï¼é£ä¹å°±éè¦æ们èªå·±å»åå页åè½ï¼
对äºå页æ¥è¯´ï¼å ¶å®å°±æ¯æ ¹æ®ç¨æ·çè¾å ¥è®¡ç®åºåºè¯¥å¨æ°æ®åºè¡¨ä¸çèµ·å§ä½ç½®ã
1ã设å®æ¯é¡µæ¾ç¤ºæ°æ®æ¡æ°
2ãç¨æ·è¾å ¥é¡µç ï¼ç¬¬ä¸é¡µã第äºé¡µ...ï¼
3ãæ ¹æ®è®¾å®çæ¯é¡µæ¾ç¤ºæ¡æ°åå½å页ç ï¼è®¡ç®åºéè¦åæ°æ®è¡¨çèµ·å§ä½ç½®
4ãå¨æ°æ®è¡¨ä¸æ ¹æ®èµ·å§ä½ç½®åå¼ï¼é¡µé¢ä¸è¾åºæ°æ®
éæ±åæ¥äºï¼éè¦å¨é¡µé¢ä¸æ¾ç¤ºå页ç页é¢ãå¦ï¼ï¼»ä¸ä¸é¡µï¼½ï¼»1][2][3][4][5][ä¸ä¸é¡µï¼½
1ã设å®æ¯é¡µæ¾ç¤ºæ°æ®æ¡æ°
2ãç¨æ·è¾å ¥é¡µç ï¼ç¬¬ä¸é¡µã第äºé¡µ...ï¼
3ã设å®æ¾ç¤ºå¤å°é¡µå·
4ãè·åå½åæ°æ®æ»æ¡æ°
5ãæ ¹æ®è®¾å®æ¾ç¤ºå¤å°é¡µå·åæ°æ®æ»æ¡æ°è®¡ç®åºï¼æ»é¡µæ°
6ãæ ¹æ®è®¾å®çæ¯é¡µæ¾ç¤ºæ¡æ°åå½å页ç ï¼è®¡ç®åºéè¦åæ°æ®è¡¨çèµ·å§ä½ç½®
7ãå¨æ°æ®è¡¨ä¸æ ¹æ®èµ·å§ä½ç½®åå¼ï¼é¡µé¢ä¸è¾åºæ°æ®
8ãè¾åºå页htmlï¼å¦ï¼ï¼»ä¸ä¸é¡µï¼½ï¼»1][2][3][4][5][ä¸ä¸é¡µï¼½
举ä¾ï¼
å建项ç®paging_demoï¼ä¿®æ¹urls.pyï¼å¢å è·¯å¾
from app01 import views urlpatterns = [ path('admin/', admin.site.urls), path('user_list/', views.user_list), ]
ä¿®æ¹views.pyï¼å¢å è§å¾å½æ°
from django.shortcuts import render from . import paging # Create your views here. # å ¨å±ä¸´æ¶å表 data = [] for i in range(1, 302): data.append({'name': 'xx-%s' % i, 'age': i}) def user_list(request): try: page_num = int(request.GET.get('page', 1)) except Exception: page_num = 1 page_obj =paging.Pagination(page_num,len(data)) data1 = data[page_obj.start:page_obj.end] return render(request, 'user_list.html', {'user_list': data1, 'page_html': page_obj.page_html})
å¨app01ç®å½ä¸å建paging.py
class Pagination: def __init__(self, page_num, total_num, per_page_num=10, max_show=11): self.page_num = page_num # å½å页é¢æ° self.total_num = total_num # æ»æ°æ®é self.per_page_num = per_page_num # æ¯é¡µæ¾ç¤ºæ°æ®æ¡æ° self.max_show = max_show # æå¤æ¾ç¤ºé¡µç æ° self.half_show = self.max_show // 2 # 页é¢åä¸å,ç¨æ¥å¤æå§ç»æ¾ç¤º11页 # divmod() å½æ°æé¤æ°åä½æ°è¿ç®ç»æç»åèµ·æ¥,è¿åä¸ä¸ªå å«ååä½æ°çå ç» self.total_page, more = divmod(total_num, per_page_num) # æ»é¡µç æ° if more: # å¦ææä½æ°çæ åµä¸ self.total_page += 1 # æ»é¡µæ°å 1 if self.page_num > self.total_page: # å¦æå½å页é¢æ°å¤§äºæ»é¡µç æ°æ¶ self.page_num = self.total_page # å½å页é¢æ°è®¾ç½®ä¸ºæ»é¡µç æ° elif self.page_num < 1: # å¦æå½å页é¢æ°å°äº1æ¶ self.page_num = 1 # å½å页é¢æ°è®¾ç½®ä¸º1 @property def start(self): # èµ·å§ä½ç½® return (self.page_num - 1) * self.per_page_num @property def end(self): # ç»æä½ç½® return self.page_num * self.per_page_num @property def page_html(self): # å页html代ç page_start = self.page_num - self.half_show page_end = self.page_num + self.half_show + 1 if self.page_num + self.half_show >= self.total_page: page_end = self.total_page + 1 page_start = self.total_page - self.max_show + 1 if self.page_num <= self.half_show: page_start = 1 page_end = self.max_show + 1 page_num_list = [] # æ·»å é¦é¡µ page_num_list.append('<li><a href="/user_list/?page={0}">é¦é¡µ</a></li>'.format(1)) # æ·»å ä¸ä¸é¡µ pre_page_num = self.page_num - 1 # å½ä¸ä¸é¡µå°äº1æ¶,ç¦æ¢ç¹å» if pre_page_num < 1: page_num_list.append( '<li class="disabled"><a href="/user_list/?page={0}">ä¸ä¸é¡µ</a></li>'.format(pre_page_num)) else: page_num_list.append('<li><a href="/user_list/?page={0}">ä¸ä¸é¡µ</a></li>'.format(pre_page_num)) # å¤æ页é¢éæ©ç¶æ for i in range(page_start, page_end): if i == self.page_num: page_num_list.append('<li class="active"><a href="/user_list/?page={0}">{0}</a></li>'.format(i)) else: page_num_list.append('<li><a href="/user_list/?page={0}">{0}</a></li>'.format(i)) # æ·»å ä¸ä¸é¡µ next_page_num = self.page_num + 1 # å½ä¸ä¸é¡µå¤§äºæ»é¡µç æ°æ¶,ç¦æ¢ç¹å» if next_page_num > self.total_page: page_num_list.append( '<li class="disabled"><a href="/user_list/?page={0}">ä¸ä¸é¡µ</a></li>'.format(next_page_num)) else: page_num_list.append('<li><a href="/user_list/?page={0}">ä¸ä¸é¡µ</a></li>'.format(next_page_num)) # æ·»å 尾页 page_num_list.append('<li><a href="/user_list/?page={0}">尾页</a></li>'.format(self.total_page)) page_html = ''.join(page_num_list) # å表转æ¢ä¸ºå符串 return page_html
å建user_list.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"> </head> <body> <div class="container"> <table class="table table-bordered"> <thead> <tr> <th>å§å</th> <th>å¹´é¾</th> </tr> </thead> <tbody> {% for user in user_list %} <tr> <td>{{ user.name }}</td> <td>{{ user.age }}</td> </tr> {% endfor %} </tbody> </table> </div> <div class="text-center"> <nav aria-label="Page navigation"> <ul class="pagination"> {{ page_html|safe }} </ul> </nav> </div> </body> </html>
访é®é¡µé¢ï¼ææå¦ä¸ï¼
æ»ç»ï¼å页æ¶éè¦åä¸ä»¶äºï¼
- å建å¤çå页æ°æ®çç±»
- æ ¹æ®å页æ°æ®è·åæ°æ®
- è¾åºå页HTMLï¼å³ï¼ï¼»ä¸ä¸é¡µï¼½ï¼»1][2][3][4][5][ä¸ä¸é¡µï¼½