Python開發Django框架入門(MVC與MTV模式)
Django框架
1、Django簡介
搭建Django環境
Django安裝
官方文檔
這里使用pip安裝
sudo pip3 install Django==2.0.6
測試安裝是否成功
>>> import django
>>> print(django.get_version())
2.0.6
創建Diango項目
ps:所有代碼都在Code文件夾里編寫
創建第一個Django項目:
$ cd /home/shiyanlou/Code
$ Code/ $ django-admin startproject mysite
以下是mysite目錄結構
mysite/
manage.py
mysite/
_init_.py
settings.py
urls.py
wsgi.py
這些目錄和文件的作用是:
- 外層的mysite/: 是項目的容器,可以為任意的名字。
- manage.py:一種讓你可以使用各種方式管理Django項目的命令行工具。在**mysite/**目錄下輸入
Python3 manage.py help
,查看它都能做什么。 - 內層的mysite/:包含項目,是一個純Python包。可以在包里調用它內部的任何東西。
- _init _.py:是一個空文件,告訴Python這個目錄應該被認為是一個Python包。一般,不需要去修改它。
- settings.py: Django項目的配置文件。
- urls.py:Django項目的URL聲明
- **wsgi.py:**作為項目的運行在WSGI兼容的Web服務器的入口。
啟動Django
cd /Code/mysite
python manage.py runserver
應該會看到這樣的輸出:
在瀏覽器里輸入http://
圖View127.0.0.1:8000會出現網站界面
2、視圖View
涉及的知識點
- URLconf配置
- Django 視圖
最終目的是完成一個對數據庫進行增刪改查的獨立模塊,所以我們從創建一個獨立的應用開始。
Django中,每一個應用都是一個Python包,并且遵守著相同的約定。
Django自帶一個工具,可以幫你生成應用的基本目錄,極大地提高了開發效率
cd /Code/mysite
python manage.py startapp lib
這將會創建一個名為lib的目錄,以下是它的目錄結構
lib/
_init.py_
admin.py
apps.py
migrations/
_init_.py
models.py
tests.py
views.py
開始編寫視圖
打開lib/view.py
,輸入以下代碼:
# lib/views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world!")
可以看出來,我們想要的即使在頁面中輸出hello,world!.
但僅編寫視圖函數,并不能在Django頁面上顯示出啦。如果要看到效果,需要使用URL來映射它。
在mysite/lib
目錄里新建urls,py
文件,并輸入以下代碼:
# lib/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
這樣就將應用lib里視圖函數與URL映射到了一起。
我們來詳解以下path()函數,它共有4個參數:
在上面的代碼中,route
為空意味著我們可以直接用鏈接http://localhost:8000/lib/
訪問該視圖函數,view=view.index
是調用了view.py
中的index
視圖,name
為index
代表我們可以在模板中用index來引用返回的變量。
接下來,我們需要向mysite/mysite/urls.py
告知使用應用lib的視圖。
輸入以下代碼:
# mysite/mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('lib/', include('lib.urls')),
path('admin/', admin.site.urls),
]
實現的原理就是使用了include()
函數,它允許應用其他的URLconfs。
比如使用這個地址進行請求時:http://localhost:8000/lib/
,首先在mysite/mysite/urls.py
中會截斷與此項匹配的 URL 部分,也就是lib/
,然后將剩余的字符串發送到 URLconf 以供進一步處理。
運行
到這里,我們就把index視圖添加進了URLconf。
讓我們來檢驗下它能否正常工作:
python manage.py runserver
使用瀏覽器訪問http://localhost:8000/lib/
可以可以看到頁面輸出了hello world!
3、模型Model
配置數據
Django的項目設置都包含在了mysite/mysite/sittings.py
中。對于數據庫,配置文件使用了SQLlite
作為默認的數據庫文件。對于知識初步嘗試Django的來說,這是十分方便,無需再去配置其它東西。
在實際開發中,我們會用到其它更具擴展性的數據庫。例如MYSQL
、Oracle
等。
如果選擇使用這些數據庫,需要安裝相應的數據庫綁定,然后改變配置文件中的DATABASE default
。
本例子中默認使用SQLite
數據庫,要使用其它數據庫,可以參考Django的官方文檔DATABASE
記得配置設置文件中的TIME_ZONE
為自己所在的時區,中國地區為Asia/shanghai
TIME_ZONE = 'Asia/Shanghai'
創建模型
模型是真實數據的簡明描述。它包含了存儲的數據所必要的字段和行為。Django遵循不要重復自己(DRY原則)。它的目標是讓你只需要定義數據模型,然后其它的東西你都不用關心,都會自動從模型生成。
在我們創建的圖書館應用中,需要創建一個模型Book。Book模型包括四個字段:書名、作者、出版社、出版日期。
向mysite/lib/models.py
文件中寫入如下代碼:
# lib/models.py
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=200)
author = models.CharField(max_length=100)
pub_house = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
從代碼可以看出,模型是django.db.models.Model類的子類。每個模型有一些類變量,它們都表示模型里的一個數據庫字段。
每個字段都是Field類的實例。比如字符字段是CharField,日期字段被表示為DateTImeField。這將告訴Django每個字段要處理的數據類型。
定義某些Field類實例需要參數。如上面的max_length=100
中的max_length
。這個參數的用處不止于用來定義數據結構,也用于驗證數據。
**模型
為了實現上述功能,我們首先要將lib應用安裝到我們項目中。
因為LibConfig
類寫在文件lib/apps.py
中,所以它的路徑為lib.apps.LibConfig
在設置文件中添加路徑:
# mysite/mysite/settings.py
INSTALLED_APPS = [
'lib.apps.LibConfig',
'django.contrib.admin',
...
]
現在你的Django項目會包含lib應用。 運行下面的命令:
python manage.py makemigrations lib
將會看到這樣的輸出:
再來看遷移命令會執行哪些SQL語句:
現在運行migrate命令,在數據庫里創建新定義的模型的數據表:
python3 manage.py migrate
看到如下畫面,則表示成功!
使用API
現在嘗試一下Django為我們創建的各種API:
python3 manage.py shell
使用這個命令而不是簡單的使用 “Python” 是因為 manage.py
會設置 DJANGO_SETTINGS_MODULE
環境變量,這個變量會讓 Django 根據 mysite/settings.py
文件來設置 Python 包的導入路徑。
>>>from lib.models import Book
>>>Book.objects.all() #獲取Book所有對象
<QuerySet []>
>>>from django.utils import timezone
>>>b = Book(name='Business', author='Tom', pub_house='First Press', pub_date=timezone.now()) #創建
>>>b.save() #保存
>>>b.id
1
>>>b.name
'Business'
>>>b.pub_date
datetime.datetime(2018, 7, 4, 2, 29, 7, 578323, tzinfo=<UTC>)
以上是 模型Model所學的內容
記住,改變模型需要這三步:
- 編輯
models.py
,改變模型 - 運行
python manage.py makemigrations
為模型的改變生成遷移文件。
-運行python manage.py migrate
來應用數據庫遷移。
4、模板Template
這節會使用模板來將數據庫的Book列表輸出到網頁上
模板
創建模板:
首先,在你的 mysite/lib 目錄里創建一個 templates 目錄。Django 將會在這個目錄里查找模板文件。
在 mysite/mysite/settings.py
文件中的 TEMPLATES 配置項描述了 Django 如何載入和渲染模板。默認的設置文件設置了 DjangoTemplates
后端,并設置 APP_DIRS = True
。這一選項將會讓 DjangoTemplates
在每個 INSTALLED_APPS
文件夾中尋找 templates
子目錄。
新建模板文件 lib/templates/lib/detail.html
,并向其中寫入如下代碼:
# lib/templates/lib/detail.html
<h1>Book List</h1>
<table>
<tr>
<td>書名</td>
<td>作者</td>
<td>出版社</td>
<td>出版時間</td>
</tr>
{% for book in book_list.all %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.pub_house }}</td>
<td>{{ book.pub_date }}</td>
</tr>
{% endfor %}
</table>
模板統一使用點符號.來訪問變量的屬性。在示例 {{ book.name }}
中,首先 Django 嘗試對 book 對象使用字典查找(也就是使用 obj.get(str)
操作),如果失敗了就嘗試屬性查找(也就是 obj.str
操作),結果是成功了。如果這一操作也失敗的話,將會嘗試列表查找(也就是 obj[int]
操作)。
在 {% for ... in ... %}
循環中發生的函數調用:book_list.all
被解釋為 Python 代碼 book_list.objects.all()
,將會返回一個可迭代的Book
對象,這一對象可以在 {% for ... in ... %}
標簽內部使用。
視圖
現在我們要創建視圖來返回圖書列表:
# mysite/lib/views.py
from django.shortcuts import render
from .models import Book
def detail(request):
book_list = Book.objects.order_by('-pub_date')[:5]
context = {'book_list': book_list}
return render(request, 'lib/detail.html', context)
在此視圖函數detail
中,首先將數據庫的Book列表按照pub_date
時間來排序,存儲到變量book_list
中。
「載入模板,填充上下文,再返回由它生成的 HttpResponse 對象」是一個非常常用的操作流程。于是 Django 提供了一個快捷函數render()
。
render()
函數把request對象作為它的第一個參數,模板作為第二個參數,字典作為它的可選的第三個參數。它返回給定模板呈現的給定文本的一個HttpResponse
對象。
在這里,context
信息將會返回到模板lib/detail.html
。
綁定鏈接
將新視圖添加進lib.urls模塊里:
# lib/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('detail/', views.detail, name='detail'),
]
運行項目看是否成功
python manage.py runserver
5、使用MVT模式實現數據庫增刪改查
表單設計
在上一個實驗中的lib/templates/lib/detail.html
里,添加一個表單。
<form action="{% url 'addBook' %}" method="post" name="addBook">
{% csrf_token %}
<p><span>書名:</span><input type="text" name="name"></p>
<p><span>作者:</span><input type="text" name="author"></p>
<p><span>出版社:</span><input type="text" name="pub_house"></p>
<input type="submit" value="添加">
</form>
簡要說明:
-上面的模板是輸入相應的書名、作者和出版社后,點擊添加,將數據存儲到數據庫并刷新頁面顯示出來。
-
我們設置表單的
action="{% url 'addBook' %}"
,并設置method="post"
。使用method="post"
(與其相對的是method="get"
)是非常重要的,因為這個提交表單的行為會改變服務器端的數據,無論何時,當你需要創建一個改變服務器端數據的表單時,請使用method="post"
。這不是 Django 的特定技巧,這是優秀的網站開發技巧。 -
由于我們創建一個 POST 表單(它具有修改數據的作用),所以我們需要小心跨站點請求偽造。 但你不必太過擔心,因為 Django 已經擁有一個用來防御它的非常容易使用的系統。 簡而言之,所有針對內部 URL 的 POST 表單都應該使用
{% csrf_token %}
模板標簽。
命名空間,多個應用以防混淆
本項目只有一個應用lib 。在一個真實的 Django 項目中,可能會有五個,十個,二十個,甚至更多應用。Django 如何分辨重名的 URL 呢?
舉個例子,lib 應用有 detail 視圖,可能另一個博客應用也有同名的視圖。Django 如何知道 {% url %}
標簽到底對應哪一個應用的 URL 呢?
答案是:在根 URLconf 中添加命名空間。在 lib/urls.py
文件中稍作修改,加上 app_name
設置命名空間:
from django.urls import path
from . import views
app_name = 'lib' #添加這行
urlpatterns = [
path('', views.index, name='index'),
path('detail/', views.detail, name='detail'),
]
現在回到 lib/templates/lib/detail.html
更改action
:
<form action="{% url 'lib:addBook' %}" method="post"
添加書籍功能
在lib/urls.py
里添加URL地址映射:
# lib/urls.py
path('addBook/', views.addBook, name='addBook')
,
然后創建addBook
函數來實現我們添加書籍的功能。
將下面的代碼添加到lib/views.py
:
# lib/views.py
from django.http import HttpResponseRedirect
from django.urls import reverse
def addBook(request):
if request.method == 'POST':
temp_name = request.POST['name']
temp_author = request.POST['author']
temp_pub_house = request.POST['pub_house']
from django.utils import timezone
temp_book = Book(name=temp_name, author=temp_author, pub_house=temp_pub_house, pub_date=timezone.now())
temp_book.save()
#重定向
return HttpResponseRedirect(reverse('lib:detail'))
簡單說明:
-
request.POST
是一個類字典對象,可以通過關鍵字的名字獲取提交的數據。 這個例子中,request.POST['name']
以字符串形式返回name的值。request.POST
的值永遠是字符串。 -
在添加書籍之后,代碼返回一個
HttpResponseRedirect
而不是常用的HttpResponse
,HttpResponseRedirect
只接收一個參數:用戶將要被重定向的 URL。 -
你應該在每次處理POST數據時,都返回
HttpResponseRedirect
。這也不是 Django 的特定技巧,這是優秀的網站開發的實踐。 -
在這個例子中,我們在
HttpResponseRedirect
的構造函數中使用reverse()
函數。這個函數避免了我們在視圖函數中硬編碼 URL。它需要我們給出想要跳轉的視圖的名字和該視圖所對應的 URL 模式中需要給該視圖提供的參數。reverse()
調用后將返回這樣一個字符串:/lib/detail/
.
添加書籍功能完成,現在可以隨意添加書籍。
訪問鏈接http://127.0.0.1:8000/lib/detail/
查看效果:
刪除書籍
刪除書籍功能實現起來也很簡單。
首先,在lib/detail.html
中設計我們的模板。
{% for book in book_list.all %}
<tr>
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.pub_house }}</td>
<td>{{ book.pub_date }}</td>
<td><a href="{% url 'lib:delBook' book.id %}">刪除</a></td>
</tr>
{% endfor %}
</table>
可以看出,只需要在每個書籍后面添加一個刪除的按鈕。刪除時也傳遞了需要刪除的圖書的id
。
接著,配置url,只需在lib/urls.py
中添加這一行:
# lib/urls.py
path('delBook/<int:book_id>', views.deleteBook, name='delBook'),
這里<int:book_id>
是接收傳遞的參數book_id
。
最后設計視圖函數:
# lib/views.py
def deleteBook(request, book_id):
bookID = book_id
Book.objects.filter(id=bookID).delete()
return HttpResponseRedirect(reverse('lib:detail'))
這個視圖中,獲取到book的id,根據id來刪除指定書籍。最后跟上面的添加書籍函數相同,使用重定位刷新頁面。
訪問鏈接http://127.0.0.1:8000/lib/detail/
查看效果:
刪除前
刪除后
總結
到這為止呢,已經完成了對數據庫的增刪查的Django項目,
現在我們再詳細的講解下整個項目是如何實現的:
深入了解以下Django的MTV設計模式
MVC
我們先來看看著名的MVC模式。
MVC,是模型(Model)-視圖(view)-控制器(Controller)的縮寫。具體定義如下:
M:模型(Model),數據存取層,負責業務對象和數據庫對象。
V:視圖(View),與用戶的交互,負責顯示與怎樣顯示。
C:控制器(Controller),接受用戶動作,調用模型,輸出相應視圖。
三者以一種插件似的,松耦合的方式連接在一起。
MTV
Django的MTV設計模式是借鑒和遵循MVC的。
MTV具體定義如下:
M:模型(Model),負責業務對象和數據庫的關系映射。
T:模板(Template),負責如何把頁面展示給用戶。
V:視圖(View),負責業務邏輯,并在適當時候調用模型和模板
URL分發器
URL分發器的作用是將頁面請求分發給不同的視圖(View)處理,視圖再調用相應的模型(Model)和模板(Template)。
Django Web框架:
一個誤區是把MVC模式與MTV模式等價替換。其實這樣是不對的。
在MTV模式中,MVC中的View分成了視圖View(展現哪些數據)和模板Template(如何展現)2個部分,而控制器(Controller)這個要素由框架自己來實現了,我們需要做的就是把URL對應到視圖V就可以了,通過這樣的URL配置,系統將一個請求發送到一個合適的視圖。
到這Django基本入門完畢,推薦看Django官方文檔來繼續深入學習。
智能推薦
Django的MTV模式
Django的MTV模式 Model(模型):負責業務對象與數據庫的對象(ORM) Template(模版):負責如何把頁面展示給用戶 View(視圖):負責業務邏輯,并在適當的時候調用Model和Template 此外,Django還有一個urls分發器,它的作用是將一個個URL的頁面請求分發給不同的view處理,view再調用相應的Model和Template 一個Django項目可以分為很多...
Web框架以及兩種模式MVC,MTV
一、Web框架的本質 眾所周知,對于所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。 上述通過socket來實現了其本質,而對于真實開發中的python web程序來說,一般會分為兩部分:服務器程序和應用程序。服務器程序負責對socket服務器進行封裝,并在請求到來時,對請...
02 理解Django框架下MTV模式(2)
1、概述 本篇用一個簡單的示例說明Django的MTV的使用模式,具體前期準備見01內容。 2、步驟1:新建工程 1)在電腦本地新建文件夾,命名Site。 2)打開cmd命令提示符窗口,切換路徑至該文件夾。 3)使用django-admin新建工程firstsite 說明:使用命令行后會在Site文件中自動創建,其中firstsite里面的文件結構為: 3、新建一個Django app 1)使用c...
開發php框架入門
開發php框架入門 doopsPHP框架開發入門 倉庫地址 為什么要自己開發框架呢? 什么是MVC 環境準備 目錄準備 nginx配置 核心文件 入口文件 配置文件 實例化類 公共函數類 自動加載類 env配置類 路由解析類 Controller基類 Model基類 View基類 msql類 應用 數據庫部署 模型部署 控制器部署 視圖部署 應用測試 doopsPHP框架開發入門 倉庫地址 倉庫地...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...