讓我們一起聊聊 Django 框架
?Django是一個python開發者都比較熟悉的一個框架,這個屬于web方向的開發框架,而且Django是屬于大而全的,最出名的應該屬于其全自動化的管理后臺了,我們只需要使用ORM,做一些簡單的對象定義,就可以自動生成對應的數據庫的表結構,以及全功能的管理后臺。
Django框架的特點
功能較為完善,有著較高的開發效率,但是呢,性能擴展比較有限,采用Django的項目,在流量達到一定的規模之后,需要對其進行重構,才能夠滿足性能的要求,比較適合中小型的網站。
Django的設計哲學是徹底的將代碼合樣式進行分離,Django從根本上杜絕在模板中進行編碼處理數據的可能性。
Django先進的APP設計理念,APP是可以插拔的,是不可多得的思想,不需要了,可以直接刪除,對系統整體影響不大。
這一點作為一個常年的Java開發者來說必須說一句,這個設計我認為是和微服務思想中的Application是一個理念的,Java開發者最熟悉的莫過于spring全家桶,而spring全家桶大家也一定熟悉springboot,以及springcloud各種的服務治理。
我們開發的后端服務,隨著業務的發展變得越來越臃腫的時候,也就需要拆分成多個服務,而多個服務呢,做到了一個解耦合,互相調用,如果當我們需要下掉一個服務的時候,也會變得相對來說比較簡單。
Django框架也存在一定的缺點。
Django包含了一些輕量級的不常用的功能模塊,這一點不如flask框架方便。
性能相對來說比較低,當然這也不完全是框架的郭,也有一部分是python的問題,python本身就是屬于解釋性語言,其它的python框架也有同樣的問題。
WSGI協議 & uwsgi & wsgiref & Gunicorn
python web程序一般來說分為兩部分,服務器程序和應用程序,服務器程序負責對socket服務器進行封裝,并在客戶端請求服務端時將客戶端請求的各種數據和信息進行整理。
應用程序則負責具體的邏輯處理,為了方便應用程序的開發就出現了很多的web框架,Django便是其中之一,服務器程序需要為不同的web框架提供不同的支持。
因此就需要一個標準,只要服務器程序和應用程序也就是web框架都支持這個標準,服務器程序就可以web框架之間配合使用。
WSGI就是一種規范,它規定了使用python編寫的web應用程序與web服務器程序之間的接口格式。
常見的符合WSGI協議的服務器程序有uwsgi,Gunicorn,而django框架自帶的服務器程序是wsgiref,當django項目上線時可以更換成uwsgi或者Gunicorn。
Django的請求生命周期
圖片來源于網站,侵刪
1.瀏覽器發起請求。
2.WSGI創建socket服務器,接收請求HttpRequest,并將請求進行初次封裝,然后將請求交給對應的web框架Flask、Django。
3.中間件處理請求,幫助我們對請求進行校驗或者在請求對象中添加相關的數據。
4.URL路由,根據當前請求的URL找到對應的視圖函數,映射。
5.view視圖,進行業務處理,ORM處理數據,從數據庫取出數據返回給view視圖,view視圖將數據渲染到對應的template模板,并將數據返回。
6.中間件處理響應。
7.WSGI返回相應HttpResponse。
8.瀏覽器渲染。
列舉django中間件的5個方法?以及django中間件的應用場景?
1.process_request:接收到客戶端信息后立即執行,視圖函數之前。
2.process_response:返回到客戶端信息前最后執行,視圖函數之后。
3.process_view:拿到視圖函數的名稱,參數,執行process_view()方法。
4.process_exception:視圖函數出錯時執行。
5.process_template_response:在視圖函數執行完后立即執行,前提是視圖返回的對象中有一個render()方法。
Django中的ORM中常用的獲取數據查詢集合的方法
常用方法包括filter和exclude方法。字符串模糊匹配可以使用icontains, in等多種方法。
qs1 = Article.objects.filter(title__icontains='django')
qs2 = Article.objects.filter(id__range=[1,9])
qs3 = Article.objects.filter(id__in=[1, 3, 6, 7, 9])
qs4 = Article.objects.filter(author=request.user).exclude(id=1)
Django中的QuerySet有哪些特性
Django的QuerySet主要有兩個特性:一是惰性的(lazy),二是自帶緩存。
article_list = Article.objects.filter(title__contains="django")
當我們定義article_list的時候,Django的數據接口QuerySet并沒有對數據庫進行任何查詢。無論你加多少過濾條件,Django都不會對數據庫進行查詢。
只有當你需要對article_list做進一步運算時(比如打印出查詢結果,判斷是否存在,統計查詢結果長度),Django才會真正執行對數據庫的查詢(見下例1)。
這個過程被稱為queryset的執行(evaluation)。
Django這樣設計的本意是盡量減少對數據庫的無效操作,比如查詢了結果而不用是計算資源的很大浪費。
什么是基于函數的視圖(FBV)和基于類的視圖(CBV)以及各自的優點
FBV(function base views) 就是在視圖里使用函數處理請求。CBV(class base views) 就是在視圖里使用類處理請求。
Python是一個面向對象的編程語言,如果只用函數來開發,有很多面向對象的優點就錯失了(繼承、封裝、多態)。
所以Django在后來加入了Class-Based-View,可以讓我們用類寫View,這樣做的優點主要下面兩種:
1.提高了代碼的復用性,可以使用面向對象的技術,比如Mixin(多繼承)。
2.可以用不同的函數針對不同的HTTP方法處理,而不是通過很多if判斷,提高代碼可讀性。
你能列舉幾個減少數據庫查詢次數的方法嗎?
利用Django queryset的惰性和自帶緩存的特性。
使用select_related和prefetch_related方法在數據庫層面進行Join操作。
使用緩存。
Django的模型繼承有哪幾種方式? 它們有什么區別以及何時使用它們?
Django的模型繼承有如下3種方式:
1. 抽象模型繼承(abstract model)。
2. 多表模型繼承(multi-table inheritance)。
3. 代理模型(proxy model)。
它們的區別如下:
Django不會為抽象模型在數據庫中生成自己的數據表。父類Meta中的abstract=True也不會傳遞給子類。
如果你發現多模型有很多共同字段時,需使用抽象模型繼承。
多表模型繼承與抽象模型繼承最大的區別在于Django也會為父類模型建立自己的數據表,同時隱式地在父類和子類之間建立一個一對一關系。
如果我們只想改變某個模型的行為方法,而不是添加額外的字段或創建額外的數據表,我們就可以使用代理模型(proxy model)。設置一個代理模型,需要在子類模型Meta選項中設置proxy=True, Django不會為代理模型生成新的數據表。
django rest framework如何實現的用戶訪問頻率控制?
from rest_framework.throttling import SimpleRateThrottle。
這里使用的節流類是繼承了SimplePateThrottle類,而這個類利用了django內置的緩存來存儲訪問記錄。
通過全局節流設置,所有的視圖類默認是使用UserThrottle類進行節流,如果不想使用默認的類就自定義給throttle_classes屬性變量賦值,如:“throttle_classes = [VisitThrottle,]”。
Celery 分布式任務隊列
情景:用戶發起 request,并等待 response 返回。在本些 views 中,可能需要執行一段耗時的程序,那么用戶就會等待很長時間,造成不好的用戶體驗,比如發送郵件、手機驗證碼等。
使用 celery 后,情況就不一樣了。解決:將耗時的程序放到 celery 中執行。
將多個耗時的任務添加到隊列 queue 中,也就是用 redis 實現 broker 中間人,然后用多個 worker 去監聽隊列里的任務去執行。
任務 task:就是一個 Python 函數。
隊列 queue:將需要執行的任務加入到隊列中。
工人 worker:在一個新進程中,負責執行隊列中的任務。
代理人 broker:負責調度,在布置環境中使用 redis。?