A place for study and research

Python 100 Days Day41 Introduction to Django

|

author: jackfrued

Django快速上手

Web開發的早期階段,開發者需要手動編寫每個頁面,例如一個新聞門戶網站,每天都要修改它的HTML頁面,隨著網站規模和體量的增大,這種做法一定是非常糟糕的。為了解決這個問題,開發人員想到了用程序來為Web服務器生成動態內容,也就是說網頁中的動態內容不再通過手動編寫而是通過程序自動生成。最早的時候,這項技術被稱為CGI(公共網關接口),當然隨著時間的推移,CGI暴露出的問題也越來越多,例如大量重覆的樣板代碼,總體性能較為低下等。在時代呼喚新英雄的背景下,PHP、ASP、JSP這類Web應用開發技術在上世紀90年代中後期如雨後春筍般湧現。通常我們說的Web應用是指通過瀏覽器來訪問網絡資源的應用程序,因為瀏覽器的普及性以及易用性,Web應用使用起來方便簡單,免除了安裝和更新應用程序帶來的麻煩;站在開發者的角度,也不用關心用戶使用什麽樣的操作系統,甚至不用區分是PC端還是移動端。

Web應用機制和術語

下圖向我們展示了Web應用的工作流程,其中涉及到的術語如下表所示。

說明:相信有經驗的讀者會發現,這張圖中其實還少了很多東西,例如反向代理服務器、數據庫服務器、防火墻等,而且圖中的每個節點在實際項目部署時可能是一組節點組成的集群。當然,如果你對這些沒有什麽概念也不要緊,繼續下去就行了,後面會給大家一一講解的。

術語 解釋
URL/URI 統一資源定位符/統一資源標識符,網絡資源的唯一標識
域名 與Web服務器地址對應的一個易於記憶的字符串名字
DNS 域名解析服務,可以將域名轉換成對應的IP地址
IP地址 網絡上的主機的身份標識,通過IP地址可以區分不同的主機
HTTP 超文本傳輸協議,構建在TCP之上的應用級協議,萬維網數據通信的基礎
反向代理 代理客戶端向服務器發出請求,然後將服務器返回的資源返回給客戶端
Web服務器 接受HTTP請求,然後返回HTML文件、純文本文件、圖像等資源給請求者
Nginx 高性能的Web服務器,也可以用作反向代理負載均衡 和 HTTP緩存

HTTP協議

這里我們先費一些筆墨來說說HTTP這個協議。HTTP(超文本傳輸協議)是構建於TCP(傳輸控制協議)之上應用級協議,它利用了TCP提供的可靠的傳輸服務實現了Web應用中的數據交換。按照維基百科上的介紹,設計HTTP最初的目的是為了提供一種發布和接收HTML頁面的方法,也就是說這個協議是瀏覽器和Web服務器之間傳輸的數據的載體。關於這個協議的詳細信息以及目前的發展狀況,大家可以閱讀《HTTP 協議入門》《互聯網協議入門》系列以及《圖解HTTPS協議》這幾篇文章進行了解。下圖是我在四川省網絡通信技術重點實驗室學習和工作期間使用開源協議分析工具Ethereal(抓包工具WireShark的前身)截取的訪問百度首頁時的HTTP請求和響應的報文(協議數據),由於Ethereal截取的是經過網絡適配器的數據,因此可以清晰的看到從物理鏈路層到應用層的協議數據。

HTTP請求(請求行+請求頭+空行+[消息體]):

HTTP響應(響應行+響應頭+空行+消息體):

說明:這兩張圖是在2009年9月10日淩晨獲得的,但願這兩張如同泛黃的照片般的截圖能幫助你了解HTTP到底是什麽樣子的。當然,如果沒有專業的抓包工具,也可以通過瀏覽器提供的“開發者工具”來查看HTTP請求和響應的數據格式。

Django概述

Python的Web框架有上百個,比它的關鍵字還要多。所謂Web框架,就是用於開發Web服務器端應用的基礎設施,說得通俗一點就是一系列封裝好的模塊和工具。事實上,即便沒有Web框架,我們仍然可以通過socket或CGI來開發Web服務器端應用,但是這樣做的成本和代價在商業項目中通常是不能接受的。通過Web框架,我們可以化繁為簡,降低創建、更新、擴展應用程序的工作量。剛才我們說到Python有上百個Web框架,這些框架包括Django、Flask、Tornado、Sanic、Pyramid、Bottle、Web2py、web.py等。

在上述Python的Web框架中,Django無疑是最有代表性的重量級選手,開發者可以基於Django快速的開發可靠的Web應用程序,因為它減少了Web開發中不必要的開銷,對常用的設計和開發模式進行了封裝,並對MVC架構提供了支持(Django中稱之為MTV架構)。MVC是軟件系統開發領域中一種放之四海而皆準的架構,它將系統中的組件分為模型(Model)、視圖(View)和控制器(Controller)三個部分並借此實現模型(數據)和視圖(顯示)的解耦合。由於模型和視圖進行了分離,所以需要一個中間人將解耦合的模型和視圖聯系起來,扮演這個角色的就是控制器。稍具規模的軟件系統都會使用MVC架構(或者是從MVC演進出的其他架構),Django項目中我們稱之為MTV,MTV中的M跟MVC中的M沒有區別,就是代表數據的模型,T代表了網頁模板(顯示數據的視圖),而V代表了視圖函數,在Django框架中,視圖函數和Django框架本身一起扮演了MVC中C的角色。

Django框架誕生於2003年,它是一個在真正的應用中成長起來的項目,由勞倫斯出版集團旗下在線新聞網站的內容管理系統(CMS)研發團隊(主要是Adrian Holovaty和Simon Willison)開發,以比利時的吉普賽爵士吉他手Django Reinhardt來命名。Django框架在2005年夏天作為開源框架發布,使用Django框架能用很短的時間構建出功能完備的網站,因為它代替程序員完成了那些重覆乏味的勞動,剩下真正有意義的核心業務給程序員來開發,這一點就是對DRY(Don’t Repeat Yourself)理念的最好踐行。許多成功的網站和應用都是基於Python語言進行開發的,國內比較有代表性的網站包括:知乎、豆瓣網、果殼網、搜狐閃電郵箱、101圍棋網、海報時尚網、背書吧、堆糖、手機搜狐網、咕咚、愛福窩、果庫等,其中不乏使用了Django框架的產品。

快速上手

第一個Django項目

  1. 檢查Python環境:Django 1.11需要Python 2.7或Python 3.4以上的版本;Django 2.0需要Python 3.4以上的版本;Django 2.1和2.2需要Python 3.5以上的版本;Django 3.0需要Python 3.6以上版本。

    說明:Django框架不同版本所需的Python解釋器環境,可以在Django官方文檔的FAQ中找到。

    可以在macOS的終端中輸入下面的命令檢查Python解釋器版本,Windows系統可以在命令行提示符中輸入python --version

    python3 --version
    

    也可以在Python的交互式環境中執行下面的代碼來查看Python解釋器的版本。

    import sys
    sys.version
    sys.version_info
    
  2. 更新包管理工具並安裝Django環境(用於創建Django項目)。

    說明:在更新這個文檔時,Django最新的正式版本是3.0.7,Django 3.0提供了對ASGI的支持,可以實現全雙工的異步通信,但是目前的使用體驗一般,所以暫時不推薦大家使用Django 3.0,下面我們安裝的是Django 2.2.13版本。使用pip安裝三方庫和工具時,可以通過==來指定安裝的版本。

    pip3 install -U pip
    pip3 install django==2.2.13
    
  3. 檢查Django環境並使用django-admin命令創建Django項目(項目名稱為hellodjango)。

    django-admin --version
    django-admin startproject hellodjango
    
  4. 用PyCharm打開創建好的Djang項目,並為其添加虛擬環境。

    如上圖所示,PyCharm的項目瀏覽器中,最頂層的文件夾hellodjango是Python項目文件夾,這個文件夾的名字並不重要,Django項目也不關心這個文件夾叫什麽名字。該文件夾下有一個同名的文件夾,它是Django項目文件夾,其中包含了__init__.pysettings.pyurls.pywsgi.py四個文件,與名為hellodjango的Django項目文件夾同級的還有一個名為manage.py 的文件,這些文件的作用如下所示:

    • hellodjango/__init__.py:空文件,告訴Python解釋器這個目錄應該被視為一個Python的包。
    • hellodjango/settings.py:Django項目的配置文件。
    • hellodjango/urls.py:Django項目的URL映射聲明,就像是網站的“目錄”。
    • hellodjango/wsgi.py:項目運行在WSGI兼容Web服務器上的入口文件。
    • manage.py: 管理Django項目的腳本程序。

    說明:WSGI全稱是Web服務器網關接口,維基百科上給出的解釋是“為Python語言定義的Web服務器Web應用程序或框架之間的一種簡單而通用的接口”。

    創建虛擬環境的界面如下圖所示。

    pycharm-django-virtual-environment

  5. 安裝項目依賴項。

    方法一:打開PyCharm的終端,在終端中通過pip命令安裝Django項目的依賴項。

    說明:由於已經基於Python 3解釋器環境為項目創建了虛擬環境,所以虛擬環境中的python命令對應的是Python 3的解釋器,而pip命令對應的是Python 3的包管理工具。

    pip install django==2.2.13
    

    方法二:在PyCharm的偏好設置中,可以找到項目的解釋器環境和已經安裝的三方庫,可以通過點擊添加按鈕來安裝新的依賴項,需要提醒大家的是在安裝Django依賴項時,需要指定版本號,否則將默認安裝更新本文時最新的3.0.7版本。

    下圖展示了Django版本和Python版本的對應關系,請大家自行對號入座。

    Django版本 Python版本
    1.8 2.7、3.2、3.3、3.4、3.5
    1.9、1.10 2.7、3.4、3.5
    1.11 2.7、3.4、3.5、3.6、3.7(Django 1.11.17)
    2.0 3.4、3.5、3.6、3.7
    2.1 3.5、3.6、3.7
    2.2 3.5、3.6、3.7、3.8(Django 2.2.8)
    3.0 3.6、3.7、3.8
  6. 啟動Django自帶的服務器運行項目。

    方法一:在“Run”菜單選擇“Edit Configuration”,配置“Django server”運行項目(適用於專業版PyCharm)。

    方法二:在“Run”菜單選擇“Edit Configuration”,配置運行“Python”程序運行項目(適用於專業版和社區版PyCharm)。

    方法三:在PyCharm的終端(Terminal)中通過命令運行項目(適用於專業版和社區版PyCharm)。

    python manage.py runserver
    
  7. 查看運行效果。

在瀏覽器中輸入http://127.0.0.1:8000訪問我們的服務器,效果如下圖所示。

說明

  1. 剛剛啟動的Django自帶的服務器只能用於開發和測試環境,因為這個服務器是純Python編寫的輕量級Web服務器,不適合在生產環境中使用。
  2. 如果修改了代碼,不需要為了讓修改的代碼生效而重新啟動Django自帶的服務器。但是,在添加新的項目文件時,該服務器不會自動重新加載,這個時候就得手動重啟服務器。
  3. 可以在終端中通過python manage.py help命令查看Django管理腳本程序可用的命令參數。
  4. 使用python manage.py runserver啟動服務器時,可以在後面添加參數來指定IP地址和端口號,默認情況下啟動的服務器將運行在本機的8000端口。
  5. 在終端中運行的服務器,可以通過Ctrl+C來停止它 。通過PyCharm的“運行配置”運行的服務器直接點擊窗口上的關閉按鈕就可以終止服務器的運行。
  6. 不能在同一個端口上啟動多個服務器,因為會導致地址的沖突(端口是對IP地址的擴展,也是計算機網絡地址的一部分)。
  7. 修改項目的配置文件settings.py

Django是一個支持國際化和本地化的框架,因此剛才我們看到的Django項目的默認首頁也是支持國際化的,我們可以通過修改配置文件將默認語言修改為中文,時區設置為東八區。

找到修改前的配置(在settings.py文件第100行以後)。

   LANGUAGE_CODE = 'en-us'
   TIME_ZONE = 'UTC'

修改為以下內容。

   LANGUAGE_CODE = 'zh-hans'
   TIME_ZONE = 'Asia/Chongqing'

刷新剛才的頁面,可以看到修改語言代碼和時區之後的結果。

創建自己的應用

如果要開發自己的Web應用,需要先在Django項目中創建“應用”,一個Django項目可以包含一個或多個應用。

  1. 在PyCharm的終端中執行下面的命令,創建名為first的應用。

    python manage.py startapp first
    

    執行上面的命令會在當前路徑下創建first目錄,其目錄結構如下所示:

    • __init__.py:一個空文件,告訴Python解釋器這個目錄應該被視為一個Python的包。
    • admin.py:可以用來注冊模型,用於在Django框架自帶的管理後台中管理模型。
    • apps.py:當前應用的配置文件。
    • migrations:存放與模型有關的數據庫遷移信息。
      • __init__.py:一個空文件,告訴Python解釋器這個目錄應該被視為一個Python的包。
    • models.py:存放應用的數據模型(MTV中的M)。
    • tests.py:包含測試應用各項功能的測試類和測試函數。
    • views.py:處理用戶HTTP請求並返回HTTP響應的函數或類(MTV中的V)。
  2. 修改應用目錄下的視圖文件views.py

    from django.http import HttpResponse
       
    
    def show_index(request):
        return HttpResponse('<h1>Hello, Django!</h1>')
    
  3. 修改Django項目目錄下的urls.py文件,將視圖函數和用戶在瀏覽器中請求的路徑對應。

    from django.contrib import admin
    from django.urls import path, include
    
    from first.views import show_index
       
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('hello/', show_index),
    ]
    
  4. 重新運行項目,並打開瀏覽器中訪問http://127.0.0.1:8000/hello/

  5. 上面我們通過代碼為瀏覽器生成了內容,但仍然是靜態內容,如果要生成動態內容,可以修改views.py文件並添加如下所示的代碼。

    from random import sample
       
    from django.http import HttpResponse
       
       
    def show_index(request):
        fruits = [
            'Apple', 'Orange', 'Pitaya', 'Durian', 'Waxberry', 'Blueberry',
            'Grape', 'Peach', 'Pear', 'Banana', 'Watermelon', 'Mango'
        ]
        selected_fruits = sample(fruits, 3)
        content = '<h3>今天推薦的水果是:</h3>'
        content += '<hr>'
        content += '<ul>'
        for fruit in selected_fruits:
            content += f'<li>{fruit}</li>'
        content += '</ul>'
        return HttpResponse(content)
    
  6. 刷新頁面查看程序的運行結果,看看每次刷新的網頁的時候,是不是可以看到不一樣的內容。

總結

至此,我們已經利用Django框架完成了一個非常小的Web應用,雖然它並沒有任何的實際價值,但是可以通過這個項目對Django框架有一個感性的認識。學習Django最好的資料肯定是它的官方文檔,官方文檔提供了對多國語言的支持,而且有新手教程引導初學者學習使用Django框架,建議大家通過閱讀Django的官方文檔來學習和使用這個框架。當然圖靈社區出版的《Django基礎教程》也是非常適合初學者的入門級讀物,有興趣的讀者可以點擊鏈接進行購買。

Comments