讓我們一起聊聊 Django 框架

語言: CN / TW / HK

​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。​