歡迎大家訪問我的個人網站《劉江的博客和教程》www.liujiangblog.com
主要分享Python 及Django教程以及相關的博客!
版權所有,轉載需注明來源!
2019年7月更新。
本文面向有一些的Python基礎,但剛接觸web框架的Django初學者。
環境:Windows10 Python3.6/3.7 Pycharm2018 Django 2.2版 pip3
一、Django簡介
百度百科:一個開放源代碼的Web框架,由Python語言編寫......
重點:一個大而全的框架,啥都替你考慮好了。
1. web框架介紹
具體介紹Django之前,必須先介紹Web框架的概念。
Web框架: 別人已經設定好的一個Web網站模板,你學習它的規則,然后“填空”或“修改”成你自己需要的樣子。
一般Web框架的架構是這樣的:
其它基於Python的Web框架,如Tornado、Flask、Webpy都是在這個范圍內進行增刪裁剪的。例如Tornado用的是自己的異步非阻塞通信協議,Flask則只提供了最精簡和基本的框架,Django直接使用WSGI通信協議,並實現了大部分Web應用相關的功能。
2. MVC/MTV介紹
MVC:
百度百科:全名Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件工程典范,用業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件里面,在改進和個性化定制界面及用戶交互的同時,不需要重新編寫業務邏輯。
通俗解釋:一種代碼和文件的組織和管理形式!不要被縮寫嚇到了,這其實就是把代碼分散到不同的文件中,把不同類型的文件又放到不同目錄下的一種做法,然后取了個高大上的名字。當然,它帶來的好處有很多,比如前后端分離,松耦合等等,在使用中你慢慢體會就會逐漸明白它。
其中:
-
模型(model):定義數據庫相關的內容,一般放在models.py文件中。
-
視圖(view):定義HTML等靜態網頁文件相關,也就是那些HTML、CSS、JS等前端的東西。
-
控制器(controller):定義業務邏輯相關,就是你的主要代碼。
MTV:
Django覺得MVC的字面意思很別扭,不太符合它的理念,就給它改了一下。view不再是HTML相關,而是主業務邏輯V了,相當於控制器。HTML被放在Templates中,稱作模板T,於是MVC就變成了MTV。這其實就是一個文字游戲,和MVC本質上是一樣的,換了個名字和叫法而已,換湯不換葯。
3. Django的MTV模型組織
目錄分開,就必須有機制將他們在內里進行耦合。在Django中,典型的業務流程如下圖所示:
二、Django項目實例
1. 程序安裝
Python3.6、pip3及Pycharm請自行安裝。
(1)安裝Django:
這里只介紹較為簡單的pip3命令安裝方式。
win+r
,調出cmd,運行命令:
pip3 install django
自動安裝Pypi提供的最新的Django版本。
注意:
- 建議升級一下pip3,命令
python -m pip install --upgrade pip
- 如果你以前安裝過django,則會使用先前緩存的安裝文件
- 使用cmd,請以管理員身份運行,否則可能出現權限問題
(2)配置系統環境
成功安裝Django后,在下圖中的路徑可找到django-admin.exe
文件,將它加入操作系統環境變量中。這樣以后調用會比較方便。
運行django-admin help
,能看到下面的內容表示安裝過程OK。
或者進入Python交互式環境(注意一定要進入剛才安裝了Django的Python解釋器),按下面所示查看安裝版本:
>>> import django >>> django.get_version() 2.2
再或者使用pip list
命令,查看是否存在Django模塊。
2. 創建Django項目
在Linux等命令行界面下,使用Django提供的命令和vim也能進行項目開發。但是這里推薦使用Pycharm這個目前最好的Python開發IDE,它功能強大,界面友好。(下面所有的操作都在Pycharm中進行。)
點擊file-->new project
,出現下面的對話框。
選擇Django欄目,輸入項目名稱,這里采用國際慣例的mysite。選擇先前安裝好Django2.2的Python解釋器版本,點擊create創建。(注:這里暫不考慮虛擬環境問題)
選擇open in current window
,在當前窗口打開。
Django將自動生成下面的目錄結構:
與項目同名的mysite目錄中是項目核心文件。templates目錄是HTML文件存放處(這是Pycharm安利給我們的),也就是MTV中的T。manage.py
是Django項目管理文件。
3. 創建APP
在每個Django項目中可以包含多個APP,相當於一個大型項目中的分系統、子模塊、功能部件等等,相互之間比較獨立,但也可以有聯系。所有的APP共享項目資源。
在Pycharm下方的Terminal終端中輸入命令:
python manage.py startapp login
這樣就創建了一個叫做login的APP,django自動生成“login”文件夾,及一系列文件:
4. 編寫路由
路由是瀏覽器輸入url,在Django服務器響應url的轉發中心。路由都寫在urls文件里,它將瀏覽器輸入的url映射到相應的業務處理邏輯也就是視圖。簡單的urls編寫方法如下圖:
5. 編寫視圖函數
路由轉發用戶請求到視圖函數。視圖函數處理用戶請求,也就是編寫業務處理邏輯,一般都在views.py
文件里。我們下面寫一個簡單的視圖函數:
通過上面兩個步驟,我們將index
這個url指向了views里的index()
視圖函數,它接收用戶請求,並返回一個“hello world”字符串。
6. 運行web服務
現在我們已經可以將web服務運行起來了。
命令行的方式是:
python manage.py runserver 127.0.0.1:8000
但在Pycharm中,你可以這么干,在上部工具欄中找到下面圖示的圖標。
點擊下拉箭頭:
點擊edit configurations
:
在host中填入127.0.0.1
,port中填入8000。
OK確定之后,點擊綠色的三角,web服務就運行起來了。
然后按下圖所示點擊鏈接:
自動跳轉到瀏覽器程序界面。顯示的卻是下圖的404頁面:
修改一下url,添加“/index/”,就一切ok了!
可以看到我們的'Hello World!'歡迎詞了!
至此,一個最簡單的Django編寫的web服務就啟動成功了。
7. 返回HTML文件
上面我們返回給用戶瀏覽器的是什么?一個字符串!實際上這肯定不行,通常我們都是將HTML文件返回給用戶。
下面,我們在templates目錄中新建一個index.html
文件:
代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <h1 style="color: black">Hello World!</h1> </body> </html>
再回到views.py文件,編輯index視圖,注釋當前的return語句,導入render方法,換上新的return語句:
為了讓django知道我們的HTML文件在哪里,需要修改settings文件的相應內容。但默認情況下,它正好適用,你無需修改。
接下來,我們可以重新啟動web服務。在瀏覽器刷新一下,你會看到帶有樣式的“Hello World”。
注:這里有個小技巧,在多次頻繁重啟服務時,可能會不能及時釋放端口,容易啟動不了服務,修改一下端口就OK了。
8. 使用靜態文件
我們已經可以將HTML文件返還給用戶了,但是這還不夠,前端三大塊HTML、CSS、JavaScript,還有各種插件,它們齊全才是一個完整的頁面。在Django中,一般將這些靜態文件放在static目錄中。
接下來,在mysite中新建一個static目錄。(下面導入的靜態文件僅用於流程展示,並不實際使用它做點什么。)
你的CSS、JS和各種插件都可以放置在這個目錄里。比如這里,我們又在static下新建了一個js目錄,然后拷貝了一個jquery-3.2.1.min.js
進來:
為了讓Django知道這個static目錄的存在,並能夠找到這個目錄,需要對settings進行配置:
現在,我們就可以在index.html
中引入js文件了:
重新啟動web服務,刷新瀏覽器,查看結果。當然,你啥都看不出來,因為僅僅引入了一個jqurey而已,^-^.
9. 接收用戶發送的數據
前面,我們將一個要素齊全的HTML文件返還給了用戶瀏覽器。但這還不夠,因為web服務器和用戶之間沒有動態交互。
下面我們設計一個表單,讓用戶輸入用戶名和密碼,提交給index這個url,服務器將接收到這些數據。
先修改index.html
文件。刪除原來的內容,寫入下面的內容:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首頁</title> </head> <body> <h1>用戶輸入:</h1> <form action="/index/" method="post"> 用戶名:<input type="text" name="username" /><br /> 密碼:<input type="password" name="password" /><br /> <input type="submit" value="提交" /> </form> </body> </html>
重啟web服務,刷新頁面,如下圖所示:
這時候我們先不要往輸入框內輸入信息。我們先修改views.py文件:
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. def index(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') print(username, password) return render(request, 'index.html')
重啟web服務,刷新index頁面,然后我們隨便輸入點什么東西,點擊提交,結果出現了下面的403頁面。
這是因為django有一個跨站請求保護機制,這需要我們在index.html
文件中加入一行{% csrf_token %}
。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首頁</title> </head> <body> <h1>用戶輸入:</h1> <form action="/index/" method="post"> {% csrf_token %} <!--加入這行 --> 用戶名:<input type="text" name="username" /><br /> 密碼:<input type="password" name="password" /><br /> <input type="submit" value="提交" /> </form> </body> </html>
再次進入瀏覽器,刷新index頁面,輸入點東西,這次就能成功提交了,然后我們在Pycharm中可以看到print語句打印出來的相應數據了。
10. 返回動態頁面
現在,我們收到了用戶的數據,但返回給用戶的依然是個靜態頁面。通常我們會根據用戶的數據,進行處理后再返回給用戶。
先改造views.py文件:
from django.shortcuts import render from django.shortcuts import HttpResponse # Create your views here. user_list = [] def index(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') print(username, password) temp = {'user': username, 'pwd': password} user_list.append(temp) return render(request, 'index.html', {'data': user_list})
再改造index.HTML
文件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首頁</title> </head> <body> <h1>用戶輸入:</h1> <form action="/index/" method="post"> {% csrf_token %} <!--加入這行 --> 用戶名:<input type="text" name="username" /><br /> 密碼:<input type="password" name="password" /><br /> <input type="submit" value="提交" /> </form> <h1>用戶展示:</h1> <table border="1"> <thead> <tr>用戶名</tr> <tr>密碼</tr> </thead> <tbody> {% for item in data %} <tr> <td>{{ item.user }}</td> <td>{{ item.pwd }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
說明:Django采用自己的模板語言,類似jinja2,根據提供的數據,替換掉HTML中的相應部分,詳細語法入門后再深入學習。
接下來,重啟服務,刷新瀏覽器,多輸入幾次。
可以看到,我們獲得了用戶實時輸入的數據,並將它實時展示在了用戶頁面上,這是個不錯的交互過程。在Pycharm中,我們也能看到每次輸入的數據。
11. 使用數據庫
流程走到這里,django的MTV框架基本已經浮出水面了,只剩下最后的數據庫部分了。
上面我們雖然和用戶交互得很好,但並沒有保存任何數據,頁面一旦關閉,或服務器重啟,一切都將回到原始狀態。
使用數據庫的需求是毫無疑問的,Django通過自帶的ORM框架操作數據庫,並且原生支持輕量級的sqlite3數據庫。下面我們來看一看:
使用數據庫前,我們需要注冊app:
不注冊它,你的數據庫就不知道該給哪個app創建表。
然后我們在settings中,配置數據庫相關的參數,如果使用sqlite3,則不需要做任何修改。
再編輯models.py
文件,也就是MTV中的M。
from django.db import models # Create your models here. class UserInfo(models.Model): user = models.CharField(max_length=32) pwd = models.CharField(max_length=32)
這里我們創建了2個字段,分別保存用戶的名字和密碼。
接下來要在Pycharm的Teminal中通過命令創建數據庫的表了。有2條命令,分別是:
python manage.py makemigrations
這會在login目錄中的migrations目錄中生成一個0001_initial.py
遷移記錄文件。
再輸入命令:
python manage.py migrate
運行結果如下:
D:\work\for_test\mysite>python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, login, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying admin.0003_logentry_add_action_flag_choices... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying auth.0009_alter_user_last_name_max_length... OK Applying login.0001_initial... OK Applying sessions.0001_initial... OK
這樣,我們就在數據庫中將所有app的數據表都創建好了。我們可以看到項目根目錄下出現了一個db.sqlite3
文件:
現在,我們來修改views.py中的業務邏輯
from django.shortcuts import render from login import models # 導入models文件 # Create your views here. def index(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') # 將數據保存到數據庫 models.UserInfo.objects.create(user=username, pwd=password) # 從數據庫中讀取所有數據,注意縮進 user_list = models.UserInfo.objects.all() return render(request, 'index.html', {'data': user_list})
重啟web服務后,刷新瀏覽器頁面,之后和用戶交互的數據都能保存到數據庫中。任何時候都可以從數據庫中讀取數據,展示到頁面上,不會因為服務器中途關閉,丟失先前的數據了。
至此,一個要素齊全,主體框架展示清晰的Django項目完成了,其實很簡單是不是?
全文其實並不是規范的Django項目開發和代碼結構,但它夠簡單,而這是對新手最重要的!
三、 Django使用總結
Django作為Python必學Web框架,它的功能強大,內容全面,但同時也意味着限制頗多,靈活性低,可修改性差,這就是魚和熊掌不可兼得了。我們學習Django,其實就是在學習一個軟件,首先要理解它的基本原理,把握它的整體框架,牢記一些基本規則,剩下的就是不斷深入細節,然后熟能生巧、經驗多少的問題了,不存在多高深的不可掌握的技術。
最后,原創不易,版權所有,轉載需授權。