一 django 生命週期html
二 django中間鍵前端
1.什麼是中間鍵web
官方的說法:中間件是一個用來處理Django的請求和響應的框架級別的鉤子。它是一個輕量、低級別的插件系統,用於在全局範圍內改變Django的輸入和輸出。每一箇中間件組件都負責作一些特定的功能。ajax
簡單來講就至關於django門戶,保安:它本質上就是一個自定義類,類中定義了幾個方法。數據庫
請求的時候須要先通過中間件才能到達django後端(urls,views,templates,models);django
響應走的時候也須要通過中間件才能到達web服務網關接口後端
2.中間件用途:瀏覽器
#1.網站全局的身份校驗,訪問頻率限制,權限校驗...只要是涉及到全局的校驗你均可以在中間件中完成
#2.django的中間件是全部web框架中 作的最好的微信
3.注意:cookie
django默認有七個中間件,可是django暴露給用戶能夠自定義中間件而且裏面能夠寫五種方法
默認的七個中間鍵
五個方法及執行時機:
##下面的從上往下仍是從下往上都是按照註冊系統來的##
#須要咱們掌握的方法有 1.process_request(self,request)方法 規律: 1.請求來的時候 會通過每一箇中間件裏面的process_request方法(從上往下) 2.若是方法裏面直接返回了HttpResponse對象 那麼再也不往下執行,會直接原路返回並執行process_response()方法(從下往上) 基於該特色就能夠作訪問頻率限制,身份校驗,權限校驗 2. process_response(self,request,response)方法 規律: 1.必須將response形參返回 由於這個形參指代的就是要返回給前端的數據 2.響應走的時候 會依次通過每個中間件裏面的process_response方法(從下往上) #須要瞭解的方法 3. process_view(self,request,view_func,view_args,view_kwargs) 1.在路由匹配成功執行視圖函數以前 觸發執行(從上往下) 4.process_exception(self, request, exception) 1.當你的視圖函數報錯時 就會自動執行(從下往上) 5.process_template_response(self, request, response) 1.當你返回的HttpResponse對象中必須包含render屬性纔會觸發(從下往上) def index(request): print('我是index視圖函數') def render(): return HttpResponse('什麼鬼玩意') obj = HttpResponse('index') obj.render = render return obj 總結:你在書寫中間件的時候 只要形參中有repsonse 你就順手將其返回 這個reponse就是要給前端的消息
4.如何自定義中間件
#1.先建立與app應用同級目錄的任意文件夾
#2.在文件夾內建立任意名py文件
#3.在py文件中編寫自定義中間鍵(類)注意幾個固定語法和模塊導入
1.py文件中必需要導入的模塊 from django.utils.deprecation import MiddlewareMixin 2.自定義中間鍵的類必需要繼承的父類 MiddlewareMixin 3.總體例:
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse
class MyMdd(MiddlewareMixin):
def process_request(self,request):
print('我是第一個中間件裏面的process_request方法')
def process_response(self,request,response):
print('我是第一個中間件裏面的process_response方法')
return response
def process_view(self,request,view_func,view_args,view_kwargs):
print(view_func)
print(view_args)
print(view_kwargs)
print('我是第一個中間件裏面的process_view方法')
def process_exception(self, request, exception):
print('我是第一個中間件裏面的process_exception')
def process_template_response(self, request, response):
print('我是第一個中間件裏面的process_template_response')
return response
#4.settings.py文件中配置自定義的中間件(總體示例)
三 csrf跨站請求僞造
1.釣魚網站
#1.經過製做一個跟正兒八經的網站如出一轍的頁面,騙取用戶輸入信息 轉帳交易
從而作手腳
轉帳交易的請求確確實實是發給了中國銀行,帳戶的錢也是確確實實少了
惟一不同的地方在於收款人帳戶不對
#2.內部原理
在讓用戶輸入對方帳戶的那個input上面作手腳
給這個input不設置name屬性,在內部隱藏一個實現寫好的name和value屬性的input框
這個value的值 就是釣魚網站受益人帳號
#3.防止釣魚網站的思路
網站會給返回給用戶的form表單頁面 偷偷塞一個隨機字符串
請求到來的時候 會先比對隨機字符串是否一致 若是不一致 直接拒絕(403)
該隨機字符串有如下特色
1.同一個瀏覽器每一次訪問都不同
2.不一樣瀏覽器絕對不會重複
2.實際用法
#這時候就不須要註釋settings.py文件中的中間件了
#1.經過form表單提交數據實際用法
1.form表單發送post請求的時候 須要你作得僅僅書寫一句話 {% csrf_token %} 示例: <form action="" method="post"> {% csrf_token %} <p>username:<input type="text" name="username"></p> <p>password:<input type="text" name="password"></p> <input type="submit"> </form>
#2.經過ajax提交數據的三種用法
1.如今頁面上寫{% csrf_token %},利用標籤查找 獲取到該input鍵值信息(不推薦) $('[name=csrfmiddlewaretoken]').val() 例: {'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()} 2.直接書寫'{{ csrf_token }}' 例:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'} 3.你能夠將該獲取隨機鍵值對的方法 寫到一個js文件中,以後只須要導入該文件便可具體操做以下 #1.static新建一個js任意名文件 存放如下代碼 見其餘代碼 #2.在html文件中引入剛纔的js文件(以setjs.js文件 爲例) <script src="{% static 'setjs.js' %}"></script> #3.直接正常編寫ajax代碼 整體示例 $('#b1').click(function () { $.ajax({ url:'', type:'post', // 第一種方式 data:{'username':'jason','csrfmiddlewaretoken':$('[name=csrfmiddlewaretoken]').val()}, // 第二種方式 data:{'username':'jason','csrfmiddlewaretoken':'{{ csrf_token }}'}, // 第三種方式 :直接引入js文件 data:{'username':'jason'}, success:function (data) { alert(data) } })
第三種方式的js文件代碼
function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); 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", csrftoken); } } });
3.處理不一樣場景的校驗方式(當settings.py的中間件 不鍵註釋時:全局校驗,註釋時:全局不校驗)
#1.當你網站全局都須要校驗csrf的時候 有幾個不須要校驗該如何處理(全局校驗,單個不校驗)
#1.首先導入模塊 from django.views.decorators.csrf import csrf_exempt,csrf_protect #給fbv加裝飾器:@csrf_exempt @csrf_exempt def login(request): return HttpResponse('login')
#2.當你網站全局不校驗csrf的時候 有幾個須要校驗又該如何處理(全局不校驗,單個校驗)
#1.首先導入模塊 from django.views.decorators.csrf import csrf_exempt,csrf_protect #給fbv加裝飾器:@csrf_protect @csrf_protect def show(request): return HttpResponse('lll')
#3.給cbv裝飾的時候
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt, csrf_protect # 這兩個裝飾器在給CBV裝飾的時候 有必定的區別 若是是csrf_protect 那麼有三種方式 # 第一種方式 # @method_decorator(csrf_protect,name='post') # 有效的 class MyView(View): # 第三種方式 # @method_decorator(csrf_protect) def dispatch(self, request, *args, **kwargs): res = super().dispatch(request, *args, **kwargs) return res def get(self, request): return HttpResponse('get') # 第二種方式 # @method_decorator(csrf_protect) # 有效的 def post(self, request): return HttpResponse('post') 若是是csrf_exempt 只有兩種(只能給dispatch裝) 特例 @method_decorator(csrf_exempt, name='dispatch') # 第二種能夠不校驗的方式 class MyView(View): # @method_decorator(csrf_exempt) # 第一種能夠不校驗的方式 def dispatch(self, request, *args, **kwargs): res = super().dispatch(request, *args, **kwargs) return res def get(self, request): return HttpResponse('get') def post(self, request): return HttpResponse('post')
拓展:cbv登陸裝飾器的幾種方式
CBV加裝飾器 # @method_decorator(login_auth,name='get') # 第二種 name參數必須指定 class MyHome(View): @method_decorator(login_auth) # 第三種 get和post都會被裝飾 def dispatch(self, request, *args, **kwargs): super().dispatch(request, *args, **kwargs) # @method_decorator(login_auth) # 第一種 def get(self, request): return HttpResponse('get') def post(self, request): return HttpResponse('post')
四 Auth認證模塊
1.什麼是Auth模塊:Auth模塊是Django自帶的用戶認證模塊,它默認使用 auth_user 表來存儲用戶數據(能夠經過其餘操做來使用別的表)。主要解決開發一個網站用戶系統的註冊、用戶登陸、用戶認證、註銷、修改密碼等功能。執行數據庫遷移命令以後 會生成不少表 其中的auth_user是一張用戶相關的表格。
2.如何使用
#1.基本使用
#導入模塊 from django.contrib import auth 1.查詢(條件至少要爲2個) :對象=auth.authenticate(條件1,條件2) user_obj = auth.authenticate(username=username,password=password) # 必需要用 由於數據庫中的密碼字段是密文的 而你獲取的用戶輸入的是明文 2.記錄狀態:auth.login(request,對象) auth.login(request,user_obj) # 將用戶狀態記錄到session中 3.註銷:auth.logout(request) auth.logout(request) # request.session.flush() 4.判斷用戶是否登陸 ,若是執行過了 auth.login(request,對象) 結果就爲Ture print(request.user.is_authenticated) 5.登陸認證裝飾器2種方式:校驗用戶是否登陸 第一種方式: from django.contrib.auth.decorators import login_required @login_required(login_url='/xxx/') # 局部配置,'/xxx/'爲登陸視圖函數的url地址 def index(request): pass 第二種方式: from django.contrib.auth.decorators import login_required @login_required def index(request): pass settings.py文件中配置 LOGIN_URL = '/xxx/' # 全配置,'/xxx/'爲登陸視圖函數的url地址
from django.contrib import auth 1.密碼: #驗證密碼是否正確:request.user.check_password(密碼) is_right = request.user.check_password(old_password) #修改密碼 request.user.set_password(new_password) request.user.save() # 修改密碼的時候 必定要save保存 不然沒法生效 #示例 # 修改用戶密碼 @login_required # 自動校驗當前用戶是否登陸 若是沒有登陸 默認跳轉到 一個莫名其妙的登錄頁面 def set_password(request): if request.method == 'POST': old_password = request.POST.get('old_password') new_password = request.POST.get('new_password') # 先判斷原密碼是否正確 is_right = request.user.check_password(old_password) # 將獲取的用戶密碼 自動加密 而後去數據庫中對比當前用戶的密碼是否一致 if is_right: print(is_right) # 修改密碼 request.user.set_password(new_password) request.user.save() # 修改密碼的時候 必定要save保存 不然沒法生效 return render(request,'set_password.html') 2.建立用戶 from django.contrib.auth.models import User # User.objects.create_user(username =username,password=password) # 建立普通用戶 User.objects.create_superuser(username =username,password=password,email='123@qq.com') # 建立超級用戶 郵箱必填 示例: from django.contrib.auth.models import User def register(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') user_obj = User.objects.filter(username=username) if not user_obj: # User.objects.create(username =username,password=password) # 建立用戶名的時候 千萬不要再使用create 了 # User.objects.create_user(username =username,password=password) # 建立普通用戶 User.objects.create_superuser(username =username,password=password,email='123@qq.com') # 建立超級用戶 return render(request,'register.html')
#2.自定義auth_user表
在models.py文件中配置 #1.導入模塊 from django.contrib.auth.models import AbstractUser #2.建表 # 第二種方式 使用類的繼承 class Userinfo(AbstractUser): # 千萬不要跟原來表中的字段重複 只能創新 phone = models.BigIntegerField() avatar = models.CharField(max_length=32) #3.必定要在配置文件settings.py中告訴django orm再也不使用auth默認的表 而是使用你自定義的表 AUTH_USER_MODEL = 'app01.Userinfo' # '應用名.類名' #4.1.執行數據庫遷移命令,全部的auth模塊功能 所有都基於你建立的表 ,而再也不使用auth_user
五 settings功能插拔式源碼
#start.py import notify notify.send_all('國慶放假了 記住放八天哦') #settings.py NOTIFY_LIST = [ 'notify.email.Email', 'notify.msg.Msg', # 'notify.wechat.WeChat', 'notify.qq.QQ', ] #_init_ import settings import importlib def send_all(content): for path_str in settings.NOTIFY_LIST: # 1.拿出一個個的字符串 'notify.email.Email' module_path,class_name = path_str.rsplit('.',maxsplit=1) # 2.從右邊開始 按照點切一個 ['notify.email','Email'] module = importlib.import_module(module_path) # from notity import msg,email,wechat cls = getattr(module,class_name) # 利用反射 一切皆對象的思想 從文件中獲取屬性或者方法 cls = 一個個的類名 obj = cls() # 類實例化生成對象 obj.send(content) # 對象調方法 # class Email(object): def __init__(self): pass # 發送郵件須要的代碼配置 def send(self,content): print('郵件通知:%s'%content) class Msg(object): def __init__(self): pass # 發送短信須要的代碼配置 def send(self,content): print('短信通知:%s' % content) class QQ(object): def __init__(self): pass # 發送qq須要的代碼準備 def send(self,content): print('qq通知:%s'%content) class WeChat(object): def __init__(self): pass # 發送微信須要的代碼配置 def send(self,content): print('微信通知:%s'%content)