Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)
閱讀目錄
- 一、Django請求生命周期:
- 二、WEB開發模式:
- 三、cbv源碼分析:
- 四、認識RESTful
- 補充知識:跨域
- 五、基于原生django開發restful的接口
- 六、drf安裝、使用、APIView 的源碼、equset的源碼分析
一、Django請求生命周期
前端發出請求到后端,通過Django處理、響應返回給前端相關結果的過程
先進入實現了wsgi協議的web服務器—>進入django中間件—>路由f分發—>視圖(CBV或FBV)---->取模板,取數據,用數據渲染模板—>返回模板的字符串---->前端頁面得到數據展現頁面給用戶
二、WEB開發模式:
在開發Web應用中,有兩種應用模式:
前后端不分離
前后端分離
1 前后端不分離
在前后端不分離的應用模式中,前端頁面看到的效果都是由后端控制,由后端渲染頁面或重定向,也就是后端需要控制前端的展示,前端與后端的耦合度很高。
這種應用模式比較適合純網頁應用,但是當后端對接App時,App可能并不需要后端返回一個HTML網頁,而僅僅是數據本身,所以后端原本返回網頁的接口不再適用于前端App應用,為了對接App后端還需再開發一套接口。
2 前后端分離
在前后端分離的應用模式中,后端僅返回前端所需的數據,不再渲染HTML頁面,不再控制前端的效果。至于前端用戶看到什么效果,從后端請求的數據如何加載到前端中,都由前端自己決定,網頁有網頁的處理方式,App有App的處理方式,但無論哪種前端,所需的數據基本相同,后端僅需開發一套邏輯對外提供數據即可。
在前后端分離的應用模式中 ,前端與后端的耦合度相對較低。
在前后端分離的應用模式中,我們通常將后端開發的每個視圖都稱為一個接口,或者API,前端通過訪問接口來對數據進行增刪改查。
三、cbv源碼分析:
cbv–基于類的視圖,一開始我們寫視圖層的時候是基于函數來處理前端請求數據FBV,這只是一種方法,更常用的還有在視圖層使用類的方法來建立視圖層
cbv流程:
創建路由
url(r'^test/', views.Test.as_view()),—>創建類的視圖
-------------------------------------------------------------------- 注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------class Test(View):def get(self,request):return HttpResponse('cbv_get')def post(self,request):return HttpResponse('cbv_post')前端請求通過中間件進入路由—>根據路由匹配,成功后會執行后面的Test.as_view()函數,而as_view()在Django啟動的時候就會自動執行返回一個view的函數內存地址,此時路由匹配成功就會view加括號執行該函數,而view內部又調用了self.dispatch函數方法,dispatch會根據請求的方式不同,執行我們定義的類中對應請求名稱的函數方法(比如get請求,就會執行類中get的函數方法)
四、認識RESTful
即Representational State Transfer的縮寫。維基百科稱其為“具象狀態傳輸”,國內大部分人理解為“表現層狀態轉化”。
RESTful是一種開發理念。維基百科說:REST是設計風格而不是標準。 REST描述的是在網絡中client和server的一種交互形式;REST本身不實用,實用的是如何設計 RESTful API(REST風格的網絡接口),一種萬維網軟件架構風格。
我們先來具體看下RESTful風格的url,比如我要查詢商品信息,那么
非REST的url:http://…/queryGoods?id=1001&type=t01
REST的url: http://…/t01/goods/1001
可以看出REST特點:url簡潔,將參數通過url傳到服務器,而傳統的url比較啰嗦,而且現實中瀏覽器地址欄會拼接一大串字符,想必你們都見過吧。但是采用REST的風格就會好很多,現在很多的網站已經采用這種風格了,這也是潮流方向,典型的就是url的短化轉換。
那么,到底什么是RESTFul架構: 如果一個架構符合REST原則,就稱它為RESTful架構。
要理解RESTful架構,理解Representational State Transfer這三個單詞的意思。
具象的,就是指表現層,要表現的對象也就是“資源”,什么是資源呢?網站就是資源共享的東西,客戶端(瀏覽器)訪問web服務器,所獲取的就叫資源。比如html,txt,json,圖片,視頻等等。
表現,比如,文本可以用txt格式表現,也可以用HTML格式、XML格式、JSON格式表現,甚至可以采用二進制格式;圖片可以用JPG格式表現,也可以用PNG格式表現。
瀏覽器通過URL確定一個資源,但是如何確定它的具體表現形式呢?應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段才是對"表現層"的描述。
狀態轉換, 就是客戶端和服務器互動的一個過程,在這個過程中, 勢必涉及到數據和狀態的變化, 這種變化叫做狀態轉換。
互聯網通信協議HTTP協議,客戶端訪問必然使用HTTP協議,如果客戶端想要操作服務器,必須通過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。
HTTP協議實際上含有4個表示操作方式的動詞,分別是 GET,POST,PUT,DELETE,他們分別對應四種操作。GET用于獲取資源,POST用于新建資源,PUT用于更新資源,DElETE用于刪除資源。GET和POST是表單提交的兩種基本方式,比較常見,而PUT和DElETE不太常用。
而且HTTP協議是一種無狀態協議,這樣就必須把所有的狀態都保存在服務器端。因此,如果客戶端想要操作服務器,必須通過某種手段,讓服務器端發生"狀態轉化"(State Transfer)
總結
綜合上面的解釋,RESTful架構就是:
每一個URL代表一種資源;
客戶端和服務器之間,傳遞這種資源的某種表現層;
客戶端通過四個HTTP動詞,對服務器端資源進行操作,實現"表現層狀態轉化"。
RESTful規范
- API與用戶的通信協議,總是使用HTTPs協議。
- 域名
https://api.example.com 盡量將API部署在專用域名(會存在跨域問題)
https://example.org/api/ API很簡單 - 版本
URL,如:https://api.example.com/v1/
請求頭 跨域時,引發發送多次請求 - 路徑,視圖網絡上任何東西都是資源,均使用名詞表示(可復數)
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees - method,通過請求方式method 區分是什么操作
GET :從服務器取出資源(一項或多項)
POST :在服務器新建一個資源
PUT/PATCH :在服務器更新資源
DELETE :從服務器刪除資源 - 過濾,通過在url上傳參的形式傳遞搜索條件
https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件 - 狀態碼
- 錯誤處理,應返回錯誤信息,error當做key。
- 返回結果,針對不同操作,服務器向用戶返回的結果應該符合以下規范。
- Hypermedia API,RESTful
API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應
補充知識:跨域
瀏覽器的同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。”
簡單來說就是:好比在一個瀏覽器上訪問兩個不同的網站,這兩個網站頁面有自己的腳本,他們在訪問請求服務器資源時,瀏覽器會檢查它們屬于哪個網站或者說服務器,如果它跨服務器訪問了,那么瀏覽器就拒絕這種請求
瀏覽器安全的基石是 同源策略,什么是同源策略呢?言簡意賅,就是三個相同:
協議相同。
域名相同。
端口相同。
這三者相同的情況下,才被稱作 “同源”,同源策略,可以保證你的服務器的接口是隱私的。
跨域的例子:
端口不同:
假設,你的電腦現在有開啟了兩個服務器,分別在 不同的端口 :
http://localhost:8080/index.html // 發送 ajax 請求http://localhost:3000 // 提供接口在這里,這個服務器并沒有遵守 同源策略 了,此時,就產生了跨域問題。
協議不同:
舉一個很常見的例子,雙擊打開一個 html 文件,你會看到
file:///Users/xxx/Documents/index.html // 客戶端同時在瀏覽器上你會看到: http://localhost:3000 // 服務器這就是簡單的 協議不同 的跨域例子,這個例子,也是我們最好實現的例子 。。。
域名不同:
這個更明顯了:
https://www.xxx.com/index.html // 客戶端https://www.yyy.com // 服務器解決方案
1.安裝django-cors-headers
pip3 install django-cors-headers2.配置settings.py文件
INSTALLED_APPS = [...'corsheaders',...] MIDDLEWARE_CLASSES = (...'corsheaders.middleware.CorsMiddleware','django.middleware.common.CommonMiddleware', # 注意順序... ) #跨域增加忽略 CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_WHITELIST = ('*' )CORS_ALLOW_METHODS = ('DELETE','GET','OPTIONS','PATCH','POST','PUT','VIEW', )CORS_ALLOW_HEADERS = ('XMLHttpRequest','X_FILENAME','accept-encoding','authorization','content-type','dnt','origin','user-agent','x-csrftoken','x-requested-with','Pragma', )其他解決方案
1.使用JSONP
使用Ajax獲取json數據時,存在跨域的限制。不過,在Web頁面上調用js的script腳本文件時卻不受跨域的影響,JSONP就是利用這個來實現跨域的傳輸。因此,我們需要將Ajax調用中的dataType從JSON改為JSONP(相應的API也需要支持JSONP)格式。
JSONP只能用于GET請求。
2.直接修改Django中的views.py文件
修改views.py中對應API的實現函數,允許其他域通過Ajax請求數據:
def myview(_request): response = HttpResponse(json.dumps({“key”: “value”, “key2”: “value”})) response[“Access-Control-Allow-Origin”] = “*” response[“Access-Control-Allow-Methods”] = “POST, GET, OPTIONS” response[“Access-Control-Max-Age”] = “1000” response[“Access-Control-Allow-Headers”] = “*” return response五、基于原生django開發restful的接口
def books(request):# 獲取所有圖書if request.method=='GET':books=models.Book.objects.all()#把queryset對象轉成json格式字符串# ll=[]# for book in books:# bo={'name':book.name,'publish':book.publish}# ll.append(bo)#列表推導式ll=[{'name':book.name,'publish':book.publish} for book in books]response={'code':100,'msg':'查詢成功','data':ll}#safe=False 如果序列化的對象中有列表,需要設置return JsonResponse(response,safe=False,json_dumps_params={'ensure_ascii':False})六、drf安裝、使用、APIView 的源碼、equset的源碼分析
DRF:Django REST framework
Django REST framework 框架是一個用于構建Web API 的強大而又靈活的工具。
通常簡稱為DRF框架 或 REST framework。
DRF框架是建立在Django框架基礎之上,由Tom Christie大牛二次開發的開源項目。
特點
- 提供了定義序列化器Serializer的方法,可以快速根據 Django ORM 或者其它庫自動序列化/反序列化;
- 提供了豐富的類視圖、Mixin擴展類,簡化視圖的編寫;
- 豐富的定制層級:函數視圖、類視圖、視圖集合到自動生成 API,滿足各種需要;
- 多種身份認證和權限認證方式的支持;
- 內置了限流系統;
- 直觀的 API web 界面;
- 可擴展性,插件豐富
安裝、使用
-pip3 install djangorestframework -pycharm中安裝 -第一步,再寫視圖,都寫cbv from rest_framework.views import APIView class Books(APIView):pass-在setting中配置INSTALLED_APPS= [。。。。。'rest_framework']源碼分析:
APIView
1視圖類繼承了APIView之后,所有的請求都被禁用了csrf認證:
2.在APIView中as_view本質上還是調用了父類的as_view(View的as_view)
3.as_view中調用dispatch,這個dispatch是APIView的dispatch
APIView之dispatch方法:
-1、對原生的request對象做了一層包裝(面向對象的封裝),以后再用的request對象都是drf的新的request對象
-2、2 在APIView中self.initial(request, *args, **kwargs),里面有頻率控制,權限控制和認證相關
-3 根據請求方法執行咱們寫的視圖類中的相應方法
–視圖類中方法的request對象,已經變成了封裝后的request
APIView之Request方法:
-1 原生的request是self._request
-2 取以post形式提交的數據,從request.data中取(urlencoded,formdata,json格式)
-3 query_params 就是原生request的GET的數據
-4 上傳的文件是從FILES中取
-5 (重點)其他的屬性,直接request.屬性名(因為重寫了__getattr__方法)
總結
以上是生活随笔為你收集整理的Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web框架之Django_10 重要组件
- 下一篇: Django框架深入了解_02(DRF之