django實(shí)戰(zhàn)系列_第1頁(yè)
django實(shí)戰(zhàn)系列_第2頁(yè)
django實(shí)戰(zhàn)系列_第3頁(yè)
django實(shí)戰(zhàn)系列_第4頁(yè)
django實(shí)戰(zhàn)系列_第5頁(yè)
已閱讀5頁(yè),還剩101頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、django實(shí)戰(zhàn)系列(博客園專(zhuān)家thinkinside 2012年初原創(chuàng))django實(shí)戰(zhàn)系列的內(nèi)容:0. 如果你以前沒(méi)有接觸過(guò)django,你可能需要這些準(zhǔn)備知識(shí):    urlconf+mtv:django眼中的mvc    django第一步1. 實(shí)戰(zhàn)系列的開(kāi)發(fā)目標(biāo)    需求分析和設(shè)計(jì)2. 從model開(kāi)始    創(chuàng)建第一個(gè)模型類(lèi)3. model之外,你還需要知道什么    django也

2、可以有scaffold    scaffold生成物分析4. 關(guān)于界面:靜態(tài)資源,模板,及其使用    引入bootstrap,設(shè)置靜態(tài)資源    對(duì)比ror和django的模板系統(tǒng)    改造productlist界面5. 邏輯層    對(duì)比ror與django的輸入校驗(yàn)機(jī)制    實(shí)現(xiàn)product的輸入校驗(yàn)    

3、;單元測(cè)試6. 變更     修改model類(lèi)    增加目錄頁(yè),設(shè)定統(tǒng)一布局7.關(guān)于會(huì)話    在session中保存購(gòu)物車(chē)    讓頁(yè)面聯(lián)動(dòng)起來(lái)8. ajax    django實(shí)現(xiàn)restful web service    django+jquery    ajax !9. 另一輪變更 &#

4、160;  提交訂單    自定義many-to-many關(guān)系,實(shí)現(xiàn)atom訂閱    分頁(yè)(pagination)10. 用戶和權(quán)限    使用內(nèi)置的amin管理用戶    處理登錄和注銷(xiāo)    權(quán)限控制urlconf+mtv:django眼中的mvc     mvc是眾所周知的模式,即:將應(yīng)用程序分解成三個(gè)組成部分:model(模型)

5、,view(視圖),和 controller(控制 器)。其中:             m 管理應(yīng)用程序的狀態(tài)(通常存儲(chǔ)到數(shù)據(jù)庫(kù)中),并約束改變狀態(tài)的行為(或者叫做“業(yè)務(wù)規(guī)則”)。             c 接受外部用戶的操作,根據(jù)操作訪問(wèn)模型獲取數(shù)據(jù),并調(diào)用“視圖”顯示這些數(shù)據(jù)??刂破魇菍ⅰ澳P汀焙汀耙晥D”隔離,并成為二者之間的聯(lián)系紐帶。 &

6、#160;           v 負(fù)責(zé)把數(shù)據(jù)格式化后呈現(xiàn)給用戶。在agile web development with rails中有這樣一張圖對(duì)mvc模式進(jìn)行了很好的解釋?zhuān)篸jango也是一個(gè)mvc框架。但是在django中,控制器接受用戶輸入的部分由框架自行處理,所以 django 里更關(guān)注的是模型(model)、模板(template)和視圖(views),稱(chēng)為 mtv模式:m 代表模型(model),即數(shù)據(jù)存取層。 該層處理與數(shù)據(jù)相關(guān)的所有事務(wù): 如何存取、如何驗(yàn)證有效性、包含哪些行為

7、以及數(shù)據(jù)之間的關(guān)系等。t 代表模板(template),即表現(xiàn)層。 該層處理與表現(xiàn)相關(guān)的決定: 如何在頁(yè)面或其他類(lèi)型文檔中進(jìn)行顯示。v 代表視圖(view),即業(yè)務(wù)邏輯層。 該層包含存取模型及調(diào)取恰當(dāng)模板的相關(guān)邏輯。 你可以把它看作模型與模板之間的橋梁。需要注意的是,不能簡(jiǎn)單的把 django 視圖認(rèn)為是mvc控制器,把 django 模板認(rèn)為mvc視圖。 區(qū)別在于:     django 視圖 不處理用戶輸入,而僅僅決定要展現(xiàn)哪些數(shù)據(jù)給用戶;     django 模板 僅僅決定如何展現(xiàn)django視圖

8、指定的數(shù)據(jù)?;蛘哒f(shuō), django將mvc中的視圖進(jìn)一步分解為 django視圖 和 django模板兩個(gè)部分,分別決定 “展現(xiàn)哪些數(shù)據(jù)” 和 “如何展現(xiàn)”,使得django的模板可以根據(jù)需要隨時(shí)替換,而不僅僅限制于內(nèi)置的模板。至于mvc控制器部分,由django框架的urlconf來(lái)實(shí)現(xiàn)。urlconf設(shè)計(jì)非常巧妙,其機(jī)制是使用正則表達(dá)式匹配url,然后調(diào)用合適的python函數(shù)。雖然一開(kāi)始有些不習(xí)慣,但是你很快就會(huì)喜歡上它,因?yàn)閡rlconf對(duì)于url的規(guī)則沒(méi)有任何限制,你完全可以設(shè)計(jì)成任意的url風(fēng)格,不管是傳統(tǒng)的,restful的,或者是另類(lèi)的。django第一步對(duì)于一個(gè)web框架,掌

9、握了三部分的內(nèi)容,就可以說(shuō)是邁出了第一步。1. 準(zhǔn)備開(kāi)發(fā)環(huán)境2. 創(chuàng)建一個(gè)工程,并運(yùn)行3. 開(kāi)發(fā)hello world應(yīng)用1. 準(zhǔn)備環(huán)境    首先應(yīng)該是安裝python和django。這點(diǎn)官方網(wǎng)站有很詳細(xì)的說(shuō)明,網(wǎng)上也有很多教程,這里就不再重復(fù)了,只是表達(dá)一個(gè)對(duì)操作系統(tǒng)的觀點(diǎn):          mac os:對(duì)程序員和用戶都很友好          linux:    對(duì)程序員很友好 

10、;         widows:對(duì)用戶貌似友好    到底使用哪個(gè)操作系統(tǒng),仁者見(jiàn)仁。       然后是開(kāi)發(fā)工具的選擇。建議拋棄ide,使用一個(gè)好的文本編輯器。強(qiáng)烈推薦vim。但如果你選擇emacs,我無(wú)話可說(shuō)。2. 創(chuàng)建工程              django作為一個(gè)web框架,第一步應(yīng)該是能夠在瀏

11、覽器中看到頁(yè)面。如果已經(jīng)安裝好環(huán)境的話。     首先創(chuàng)建工程:django-admin.py startproject depot,即開(kāi)始創(chuàng)建名為depot的工程。     與rails相比,過(guò)程很安靜,結(jié)果很干凈。如下:      depot/             _init_.py      

12、60;      manage.py             settings.py             urls.py這幾個(gè)文件的作用如下:     _init_.py :python的模塊定義文件。 這是一個(gè)空文件,一般你不需要修改它。     man

13、age.py :一個(gè)命令行工具,生成這個(gè)文件僅僅是為了方便??梢酝ㄟ^(guò)python manage.py help 查看該工具的功能。完全不需要編輯這個(gè)文件。     settings.py :該 django 項(xiàng)目的設(shè)置或配置。      urls.py:django項(xiàng)目的url設(shè)置。 與rails不同,django初始工程的文件很少,可以很容易地閱讀所有的代碼。但這些文件已經(jīng)構(gòu)成了一個(gè)可運(yùn)行的django應(yīng)用。進(jìn)入工程目錄并運(yùn)行該工程:cd depot/python manage.py runserver

14、可以看到一些提示信息:validating models.0 errors founddjango version 1.3, using settings 'depot.settings'development server is running at :8000/quit the server with control-c.29/jan/2012 02:09:17 "get / http/1.1" 200 2049此時(shí)web server(開(kāi)發(fā)環(huán)境?。┮呀?jīng)運(yùn)行了,用瀏覽器訪問(wèn):8000/,可以看到

15、如下的界面:說(shuō)明django已經(jīng)開(kāi)始工作了。3. hello django!       與rails不同,django不需要生成controller,helper, view 等等一大堆文件,要實(shí)現(xiàn)一個(gè)hello程序,只需要幾行代碼。django web應(yīng)用中通常包含urlconf, view, template, model 四個(gè)部分(參考urlconf+mtv:django眼中的mvc)。但這些部分不是完全必需的。比如我們要實(shí)現(xiàn)一個(gè)最簡(jiǎn)單的 "hello, django!", 只需要定義urlconf和vie

16、w即可。      讓我們把“需求”明確一下,hello,django!實(shí)現(xiàn)如下功能:在瀏覽器中輸入:8000/hello, 顯示“hello django!”。首先要實(shí)現(xiàn)一個(gè)視圖(view) 來(lái)響應(yīng)請(qǐng)求。在django中視圖是一個(gè)函數(shù),該函數(shù)接受一個(gè)httprequest參數(shù),并返回一個(gè)httpresponse。我們可以在任何地方定義這個(gè)函數(shù),但通常會(huì)放在django app 的 views.py 文件中。在hello,django中我們不需要?jiǎng)?chuàng)建一個(gè)django app(因?yàn)椴恍枰猰odel),所以可

17、以在project 目錄中創(chuàng)建一個(gè)view.py 文件,并定義hello(request)視圖函數(shù):depot/views.py:python view plaincopy1. from django.http import httpresponse  2.   3. def hello(request):  4.     return httpresponse("hello, django!") 

18、; 接下來(lái)是將前面定義的url 映射到 這個(gè)視圖函數(shù)。這是由urlconf完成的。urlconf的本質(zhì)是 url 模式以及要為該 url 模式調(diào)用的視圖函數(shù)之間的映射表。打開(kāi)生成的urls.py文件,先在文件前面import剛才創(chuàng)建的view,然后在tuple類(lèi)型的變量urlpatterns中加入hello的映射關(guān)系:python view plaincopy1. from django.conf.urls.defaults import patterns, include, url  2. from&#

19、160;depot.views import hello  3.   4. urlpatterns = patterns('',  5.     url(r'hello/$', hello),  6. )   此時(shí)訪問(wèn) :8000/hello, 將會(huì)顯示 hello, django!urlconf理解起來(lái)也很容易,即 urlpatter

20、ns中的每一項(xiàng)是一個(gè)二元組(正則表達(dá)式,視圖函數(shù))。當(dāng)django 接收到http請(qǐng)求的時(shí)候,從urlpatterns中找到匹配的表達(dá)式,并將請(qǐng)求發(fā)生給對(duì)應(yīng)的視圖函數(shù),最后視圖函數(shù)返回一個(gè)http響應(yīng),交給django處理。如此而已。至此,django的第一步已經(jīng)邁出,你至少已經(jīng)可以開(kāi)始cgi風(fēng)格的web開(kāi)發(fā)了。django實(shí)戰(zhàn)(1):需求分析和設(shè)計(jì)depot是agile web development with rails中的一個(gè)購(gòu)物車(chē)應(yīng)用。該書(shū)中用多次迭代的方法,逐步實(shí)現(xiàn)購(gòu)物車(chē)應(yīng)用,使很多人走上了rails開(kāi)發(fā)的道路。遺憾的是django世界中好像沒(méi)有類(lèi)似的指引,也許是因?yàn)閜ythoner

21、 不需要具體的例子。但是如果通過(guò)這樣一個(gè)例子能夠讓更多的人加入pythoner的隊(duì)伍,也是一大幸事。本文首先回顧一下depot的需求,在后續(xù)內(nèi)容中將會(huì)按照agile web development with rails中的迭代進(jìn)度,逐步用django實(shí)現(xiàn)depot購(gòu)物車(chē)應(yīng)用。在原例子的基礎(chǔ)上,還會(huì)增加一些新的內(nèi)容,以適應(yīng)企業(yè)級(jí)應(yīng)用的開(kāi)發(fā)。同時(shí),會(huì)盡量展示敏捷開(kāi)發(fā)的特性。原書(shū)中,初始階段的需求整理如下:角色          買(mǎi)方,賣(mài)方。用例      &#

22、160;   買(mǎi)方:瀏覽產(chǎn)品,創(chuàng)建訂單          賣(mài)方:管理產(chǎn)品,處理訂單,管理發(fā)貨界面設(shè)計(jì)    買(mǎi)方界面包括:          目錄頁(yè):可以選擇一個(gè)產(chǎn)品,選中產(chǎn)品會(huì)打開(kāi)購(gòu)物車(chē)頁(yè),同時(shí)該產(chǎn)品被加入購(gòu)物車(chē)          購(gòu)物車(chē)頁(yè):顯示所有已選擇的產(chǎn)品,可以

23、返回分類(lèi)頁(yè),也可以進(jìn)入支付頁(yè)進(jìn)行支付          訂單頁(yè):填寫(xiě)一些要素信息,確認(rèn)支付后顯示收據(jù)頁(yè)          收據(jù)頁(yè):通知買(mǎi)方訂單已被接收     買(mǎi)方界面流程如下圖所示:    賣(mài)方界面包括:          登錄頁(yè):賣(mài)方要登錄后才能

24、使用系統(tǒng),登錄后通過(guò)菜單選擇其要使用的功能          菜單頁(yè):選擇維護(hù)產(chǎn)品或者查看訂單          創(chuàng)建產(chǎn)品頁(yè):用于加入新的產(chǎn)品          產(chǎn)品信息頁(yè):顯示已經(jīng)加入的產(chǎn)品,可以進(jìn)行修改或者刪除          訂單頁(yè)

25、:顯示訂單信息,可以忽略或者處理     賣(mài)方界面流程如下圖所示:領(lǐng)域模型從界面設(shè)計(jì)中可以很容易得出初步的模型,如下圖:以上,就是開(kāi)始階段所能得到的“需求”。盡管其中還有一些不確定的因素,但是敏捷方法認(rèn)為應(yīng)該盡快開(kāi)始開(kāi)發(fā),這些不確定的因素會(huì)在后續(xù)的迭代過(guò)程中逐步明確。接下來(lái),就可以開(kāi)始第一輪迭代開(kāi)發(fā)了。django實(shí)戰(zhàn)(2):創(chuàng)建第一個(gè)模型類(lèi)從模型開(kāi)始開(kāi)發(fā)似乎是個(gè)好主意。一方面模型是整個(gè)應(yīng)用的核心,實(shí)現(xiàn)了應(yīng)用的業(yè)務(wù)數(shù)據(jù)和對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行操作的約束,而視圖和模板只是向用戶提供操作和展現(xiàn)這些數(shù)據(jù)的界面;另一方面模型相對(duì)于系統(tǒng)的其他部分更加穩(wěn)定,將模型先確定下來(lái)

26、有助于系統(tǒng)其他部分的實(shí)現(xiàn)。ddd(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì))更進(jìn)一步將模型中的核心對(duì)象抽取出來(lái)作為“領(lǐng)域模型”。從depot應(yīng)用來(lái)看,產(chǎn)品(product) 應(yīng)該是模型中的核心對(duì)象之一。就讓我們先來(lái)實(shí)現(xiàn)product模型。創(chuàng)建app我們可以從django第一步中實(shí)現(xiàn)的工程開(kāi)始。在繼續(xù)之前,還要進(jìn)行一些準(zhǔn)備工作。django約定必須要?jiǎng)?chuàng)建app才能使用模型。這也是django的哲學(xué)之一:django認(rèn)為一個(gè)project包含很多個(gè)django app;project提供配置文件,比如數(shù)據(jù)庫(kù)連接信息、 安裝的app清單、模板路徑等等;而一個(gè)app是一套django功能的集合,通常包括模型和視圖,按python

27、的包結(jié)構(gòu)的方式存在。app可以在多個(gè)project之間很容易的復(fù)用。比如django自帶的注釋系統(tǒng)和自動(dòng)管理界面。所以我們?cè)谠泄こ痰幕A(chǔ)上還需要?jiǎng)?chuàng)建一個(gè)app?,F(xiàn)在假設(shè)我們只需要一個(gè)app,并將其命名為depotapp。創(chuàng)建應(yīng)用的腳本也是使用project目錄下的managy.py:$python manage.py startapp depotapp就會(huì)在工程目錄下創(chuàng)建一個(gè)depotapp目錄:depotapp/    _init_.py    models.py    tests.py &

28、#160;  views.py用python代碼定義數(shù)據(jù)庫(kù)在django的第一印象中介紹過(guò),django的設(shè)計(jì)是 以python類(lèi)的形式定義數(shù)據(jù)模型。之所以沒(méi)有采用rails的運(yùn)行時(shí)自動(dòng)獲取數(shù)據(jù)庫(kù)schema的”魔術(shù)方式“,是出于以下的考慮:     1. 效率。運(yùn)行時(shí)掃描數(shù)據(jù)庫(kù)可能會(huì)帶來(lái)性能問(wèn)題。     2. 明確性。只通過(guò)model類(lèi)就完全知道數(shù)據(jù)庫(kù)中有哪些字段,而不需要再切換到migration或schema文件中去查看,更不需要去查看數(shù)據(jù)庫(kù)結(jié)構(gòu)。    

29、3. 一致性。你看到的只是python代碼,完全不需要將大腦切換到”數(shù)據(jù)庫(kù)模式“,能極大提高開(kāi)發(fā)效率。     4. 版本控制。rails中的數(shù)據(jù)庫(kù)結(jié)構(gòu)版本保存在一個(gè)個(gè)的migration文件中,這簡(jiǎn)直就是版本管理的”反模式“。django的方式是管理model代碼文件的版本。     5. 可擴(kuò)展性??梢远x數(shù)據(jù)庫(kù)中不存在的”字段類(lèi)型“。比如email,url,等等。當(dāng)然,django也提供從現(xiàn)有數(shù)據(jù)庫(kù)表中自動(dòng)掃描生成模型的工具。so,agile web development with rails中的做法是先創(chuàng)

30、建數(shù)據(jù)庫(kù)表:sql view plaincopy1. drop table if exists products;  2. create table products (  3. id int not null auto_increment,  4. title varchar(100) not null,  5. description text 

31、;not null,  6. image_url varchar(200) not null,  7. price decimal(10,2) not null,  8. primary key (id)  9. );  然后再生成scaffold(包括model,controller,test,4個(gè)views等等)。而django的做法是,編寫(xiě)下面的model類(lèi):python view plai

32、ncopy1. depot/depotapp/models.py:  2.   3. from django.db import models  4.   5. class product(models.model):  6.      title          = models.charfie

33、ld(max_length=100)  7.      description     = models.textfield()  8.      image_url     = models.charfield(max_length=200)  9.      pri

34、ce          = models.decimalfield(max_digits=8,decimal_places=2)  如同其他的orm,id字段是默認(rèn)聲明的,不需要單獨(dú)處理.部署模型django 中的每一件事情都需要明確聲明,也就是說(shuō),沒(méi)有你的允許,django不會(huì)主動(dòng)去碰你的代碼。所以我們還需要在project中進(jìn)行一些配置工作才能讓app生效。不過(guò)這樣的配置只需要做一次。首先要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù)并配置整個(gè)project的數(shù)據(jù)庫(kù)連接,為了簡(jiǎn)單起見(jiàn),使用sql

35、ite數(shù)據(jù)庫(kù)。在工程文件夾下創(chuàng)建db文件夾和sqlite數(shù)據(jù)庫(kù)文件:$mkdir db$cd db$sqlite3 development.sqlite3然后修改配置文件settings.py, 將databases改為:python view plaincopy1. databases =   2.     'default':   3.         'engine&

36、#39;: 'django.db.backends.sqlite3',  4.         'name': 'db/development.sqlite3',  5.         'user': '',  6.     &

37、#160;   'password': '',  7.         'host': '',  8.         'port': '',  9.       

38、10.   就完成了數(shù)據(jù)庫(kù)的配置。還需要配置project讓depotapp生效,還是在settings.py中,將installed_apps改為:python view plaincopy1. installed_apps = (  2.     #'django.contrib.auth',  3.     #'django.contrib.contenttypes', 

39、0;4.     #'django.contrib.sessions',  5.     #'django.contrib.sites',  6.     #'django.contrib.messages',  7.     #'django.contrib.staticfiles',  8.

40、      9.      # uncomment the next line to enable the admin:  10.     # 'django.contrib.admin',  11.     # uncomment the n

41、ext line to enable admin documentation:  12.     # 'django.contrib.admindocs',  13.       'depot.depotapp',  14. )  接下來(lái)就可以使用模型了。先驗(yàn)證一下:$python manage.py validate0 er

42、rors found然后可以看一下這個(gè)model將會(huì)生成什么樣的數(shù)據(jù)庫(kù):$ python manage.py sqlall depotappbegin;create table "depotapp_product" (    "id" integer not null primary key,    "title" varchar(100) not null,    "description" text not null,&#

43、160;   "image_url" varchar(200) not null,    "price" decimal not null);commit;最后,將模型導(dǎo)入數(shù)據(jù)庫(kù):$ python manage.py syncdbcreating tables .creating table depotapp_productinstalling custom sql .installing indexes .no fixtures found.至此,完成了第一個(gè)模型類(lèi)的創(chuàng)建。django實(shí)戰(zhàn)(3):dja

44、ngo也可以有scaffoldrails有一個(gè)無(wú)用的”神奇“功能,叫做scaffold。能夠在model基礎(chǔ)上,自動(dòng)生成crud的界面。說(shuō)它無(wú)用,是因?yàn)閞ails的開(kāi)發(fā)者david說(shuō),scaffold”不是應(yīng)用程序開(kāi)發(fā)的目的。它只是在我們構(gòu)建應(yīng)用程序時(shí)提供支持。當(dāng)你設(shè)計(jì)出產(chǎn)品的列表該如何工作時(shí),你依賴(lài)于“支架”“生成器”產(chǎn)生創(chuàng)建,更新,和刪除的行為。然后在保留這個(gè)“動(dòng)作”時(shí)你要替換由“生成器”生成的行為。有時(shí)候當(dāng)你需要一個(gè)快速接口時(shí),并且你并不在乎界面的丑陋,“支架”就足夠用了。不要指望scaffold能滿足你程序的所有需要"。說(shuō)它神奇,是因?yàn)樵趓ails中你不清楚他是怎么實(shí)現(xiàn)的。只

45、告訴你一句話:約定優(yōu)先于配置。只要名字xxx,就會(huì)xxx。說(shuō)得人云里霧里,認(rèn)為rails真是一個(gè)偉大的框架。在django的世界中沒(méi)有這種無(wú)用的東西。但是如果你一定要,可以很容易地創(chuàng)建這么一套東西。下面我們就在project中引入一個(gè)“插件”。前面說(shuō)過(guò),app可以在多個(gè)project之間很容易的復(fù)用,我們要引入的就是一個(gè)第三方的app,無(wú)需修改,只需要簡(jiǎn)單配置即可使用。這個(gè)app叫做django-groundwork 。它不實(shí)現(xiàn)具體的功能,而是擴(kuò)展了manage.py 的命令,使得通過(guò)命令行可以生成一些代碼/文件。下載django-groundwork的代碼:$git clone $

46、ls django-groundworkauthors           license           readme.rst        django-groundwork將其中的django-groundwork文件夾復(fù)制到project文件夾,然后在settings.py中加入該app:python vi

47、ew plaincopy1. installed_apps = (  2.     #'django.contrib.auth',  3.     #'django.contrib.contenttypes',  4.     #'django.contrib.sessions',  5.    &#

48、160;#'django.contrib.sites',  6.     #'django.contrib.messages',  7.     #'django.contrib.staticfiles',  8.       9.     # uncomment the next

49、 line to enable the admin:  10.     # 'django.contrib.admin',  11.     # uncomment the next line to enable admin documentation:  12.    &

50、#160;# 'django.contrib.admindocs',  13.      'depot.depotapp',  14.     'django-groundwork',  15. )  即完成了安裝。(如果遇到了什么麻煩,也可以下載本文附帶的源代碼包)安裝后,使用$python manage.py help可以看到,列出的可用命令中多了一個(gè)groundw

51、ork。其語(yǔ)法是:$python manage.py groundwork appname modelname1 modelname2接下來(lái)使用這個(gè)app為product生成scaffold:$python manage.py groundwork depotapp product,就會(huì)生成所謂的scaffold。 此時(shí)運(yùn)行開(kāi)發(fā)服務(wù)器(python manage.py runserver),就可以訪問(wèn)下面的地址:http:/localhost:8000/depotapp/product/list/  訪問(wèn)product列表,并鏈接到create,edit,view等界面。可

52、以下載本次迭代的源代碼:django實(shí)戰(zhàn)(4):scaffold生成物分析在上一節(jié)用一個(gè)插件生成了類(lèi)似rails的scaffold,其實(shí)無(wú)非就是urlconf+mtv。讓我們看看具體都生成了哪些東西。首先是“入口”的定義即urlconf,打開(kāi)urls.py:python view plaincopy1. from django.conf.urls.defaults import patterns, include, url  2. from depot.views import hel

53、lo  3.   4. urlpatterns = patterns('',  5.      url(r'hello/ hello),  6. )  7. urlpatterns += patterns ('',  8.  (r'depotapp/', include('depota

54、pp.urls'),  9. )  上面的代碼中增加的配置行表示:以depotapp開(kāi)頭的url由depotapp/urls.py文件進(jìn)行處理。django的url配置中,除了(正則表達(dá)式,view函數(shù))的方式外,還支持(正則表達(dá)式,include文件)的方式。通常把a(bǔ)pp自身相關(guān)的url寫(xiě)到自己的url配置文件中,然后在project中引用。接下來(lái)看一下生成的depotapp/urls.py的內(nèi)容:python view plaincopy1. from django.conf.urls.defaults impo

55、rt *  2. from models import *  3. from views import *  4.   5. urlpatterns = patterns('',  6.     (r'product/create/$', create_product),  7.   &

56、#160; (r'product/list/$', list_product ),  8.     (r'product/edit/(?p<id>/+)/$', edit_product),  9.     (r'product/view/(?p<id>/+)/$', view_product),  10. )  將

57、cru(沒(méi)有d)的url映射到了視圖。而視圖在depotapp/views.py中定義:python view plaincopy1. from django import forms  2. from django.template import requestcontext  3. from django.http import httpresponse, httpresponseredirect  4. from

58、0;django.template.loader import get_template  5. from django.core.paginator import paginator  6. from django.core.urlresolvers import reverse  7.   8. # app specific files  9.   10. fro

59、m models import *  11. from forms import *  12.   13.   14. def create_product(request):  15.     form = productform(request.post or none)  16.    

60、60;if form.is_valid():  17.         form.save()  18.         form = productform()  19.   20.     t = get_template('depotapp/create_

61、product.html')  21.     c = requestcontext(request,locals()  22.     return httpresponse(t.render(c)  23.   24.   25.   26. def list_product(request):  27.  

62、0;  28.     list_items = product.objects.all()  29.     paginator = paginator(list_items ,10)  30.   31.   32.     try:  33.      

63、   page = int(request.get.get('page', '1')  34.     except valueerror:  35.         page = 1  36.   37.     try: &

64、#160;38.         list_items = paginator.page(page)  39.     except :  40.         list_items = paginator.page(paginator.num_pages)  41.  

65、60;42.     t = get_template('depotapp/list_product.html')  43.     c = requestcontext(request,locals()  44.     return httpresponse(t.render(c)  45.   46.   

66、47.   48. def view_product(request, id):  49.     product_instance = product.objects.get(id = id)  50.   51.     t=get_template('depotapp/view_product.html')  52.  

67、60;  c=requestcontext(request,locals()  53.     return httpresponse(t.render(c)  54.   55. def edit_product(request, id):  56.   57.     product_instance = product.objects.get

68、(id=id)  58.   59.     form = productform(request.post or none, instance = product_instance)  60.   61.     if form.is_valid():  62.       &

69、#160; form.save()  63.   64.     t=get_template('depotapp/edit_product.html')  65.     c=requestcontext(request,locals()  66.     return httpresponse(t.render(c)  視圖中的相關(guān)內(nèi)容比

70、較多,主要的是模板,其次還有模型類(lèi)、paginator分頁(yè)器、form表單等等?;竞w了典型的web應(yīng)用交互的內(nèi)容。django實(shí)戰(zhàn)(5):引入bootstrap,設(shè)置靜態(tài)資源之前生成了product類(lèi)的scaffold,但是如同rails的開(kāi)發(fā)者david所講的那樣,scaffold幾乎沒(méi)什么用。所以按照agile web development with rails 4th中的迭代計(jì)劃,下一步的修改是美化list頁(yè)面:但是這個(gè)界面還是太丑陋了。其實(shí),有了bootstrap后,很多站點(diǎn)都變成了“又黑又硬”的工具條+“小清新”風(fēng)格。我們即不能免俗,又懶得自已設(shè)計(jì)風(fēng)格,不妨用bootstrap

71、將產(chǎn)品清單界面重新設(shè)計(jì)成如下的風(fēng)格:下面讓我們來(lái)實(shí)現(xiàn)這個(gè)界面。顯然web界面會(huì)使用一些靜態(tài)資源(css,js,image等),要在django中引入靜態(tài)資源。django在正式部署的時(shí)候?qū)τ陟o態(tài)資源有特殊的處理(怎么處理?),在開(kāi)發(fā)階段,可以有簡(jiǎn)單的方式讓靜態(tài)資源起作用。首選在project目錄下面創(chuàng)建一個(gè)static目錄,并將靜態(tài)資源按合理的組織方式放入其中:static/      css/           bootstrap.min.c

72、ss      js/      images/      productlist.html其中productlist.html是請(qǐng)界面設(shè)計(jì)師實(shí)現(xiàn)的產(chǎn)品清單靜態(tài)頁(yè)面;css/bootstrap.min.css 是該頁(yè)面使用的樣式表,來(lái)自bootstrap,將來(lái)整個(gè)系統(tǒng)都將使用這一套樣式風(fēng)格;js目錄現(xiàn)在為空,以后可以將javascript代碼放在這里;images文件夾同理。我們可以看到,django對(duì)于靜態(tài)內(nèi)容的管理非常符合管理。相比之下,ra

73、ils要求你將靜態(tài)內(nèi)容放到很怪異的結(jié)構(gòu)中:app/assets/     images/     javascripts/     stylesheets/界面設(shè)計(jì)師實(shí)現(xiàn)的界面要想運(yùn)行起來(lái),還需要修改相關(guān)的路徑,或者改變自己的目錄設(shè)置習(xí)慣。這種設(shè)計(jì)讓人難以理解。回到django,讓靜態(tài)資源起作用只需要簡(jiǎn)單的配置(下面的做法只適用于開(kāi)發(fā)階段):修改settings.py的static files小節(jié):python view plaincopy1. import

74、0;os  2. . .  3.   4. # additional locations of static files  5. here = os.path.dirname(_file_)  6. staticfiles_dirs = (  7.     # put strings here, l

75、ike "/home/html/static" or "c:/www/django/static".  8.     # always use forward slashes, even on windows.  9.     # don't forget to use absol

76、ute paths, not relative paths.  10.     here+static_url,  11. )  然后在urls.py中增加static的url映射:python view plaincopy1. from django.contrib.staticfiles.urls import staticfiles_urlpatterns  2. . . 

77、; 3. # for development only  4. # this will only work if debug is true.  5. urlpatterns += staticfiles_urlpatterns()  啟動(dòng)server,就可以通過(guò):8000/static/productlist.html看到設(shè)計(jì)好的界面了。源代碼:在下一節(jié),終于可以修

78、改模板,美化產(chǎn)品清單頁(yè)的樣式了。django實(shí)戰(zhàn)(6):對(duì)比ror和django的模板系統(tǒng)scaffold的生成物雖然用處不大,但是給我們帶來(lái)一些最佳實(shí)踐。其中就有模板的繼承和分區(qū)。如果你深入使用過(guò)rails的模板體系,那么恭喜你:你有超強(qiáng)的忍耐力!而且更重要的是,你只需要3分鐘就可以理解django的模板體系。讓我們先回顧一下rails的模板系統(tǒng):1. 你創(chuàng)建了一個(gè)xxxview,展現(xiàn)出一些數(shù)據(jù)。2. 你意識(shí)到,各個(gè)view都有一些共同的內(nèi)容。因?yàn)閞ails也強(qiáng)調(diào)dry,所以你決定將這些共同的部分抽取出來(lái)。rails也看到了這點(diǎn),所以你很高興的看到,rails支持layout。3. rail

79、s的layout很簡(jiǎn)單,類(lèi)似html的代碼,<%= yield %>部分會(huì)被具體視圖替代,于是你很欣慰。4. 但是等等,如何指定layout?你又興奮地發(fā)現(xiàn):默認(rèn)的layout是views/layouts/application.html.erb,你可以在controller、action去指定特定的layout,甚至這種指定支持變量。在興奮之余,你完全忽視了這等于讓controller去做了view該做的事情。5. 你實(shí)現(xiàn)了一個(gè)左右結(jié)構(gòu)的layout,左側(cè)是導(dǎo)航,右側(cè)是內(nèi)容。你認(rèn)為這個(gè)layout應(yīng)該可以被多個(gè)view使用。但是你又發(fā)現(xiàn)不同的view需要的導(dǎo)航是不同的。由于存在幾

80、個(gè)view使用一種導(dǎo)航、另外幾個(gè)view使用另一個(gè)導(dǎo)航的情況,由于dry,rails說(shuō),我有partial。在view中可以使用<%= render "foo/bar" %>,甚至可以使用變量:<%= render mypartial %>然后在controller/action中指定具體的partial。:render :partial => foo/bar。盡管,controller更進(jìn)一步干預(yù)了view的細(xì)節(jié);盡管,你又要記?。簆artial: foo/bar 意味著 views/foo/_bar.html.erb.6. 如果view中的

81、多塊內(nèi)容要插到layout的不同地方怎么辦?除了主要的內(nèi)容外,你還可以在view中定義:ruby view plaincopy1. <% content_for :foo do %>    2.     foo foo foo  3. <% end %>  4. <% content_for :bar do %>

82、   5.     bar bar bar  6. <% end %>  7.   8. <div>下面居然就是主要內(nèi)容了<div>  然后這些內(nèi)容塊會(huì)分別插入到layout的<%= yield :foo %> <%= yield :bar %> 和<%= yield %>的地方。7. 還有,還有,<%= stylesheet_l

83、ink_tag "application" %>, <%= javascript_include_tag "html5" %> 到這里,你可以說(shuō)自己已經(jīng)了解rails的模板系統(tǒng)了嗎?接下來(lái)我們可以放松心情了,因?yàn)閐jango的模板很容易理解,除了基本的變量、標(biāo)簽、過(guò)濾器等之外,模板的關(guān)系只有兩個(gè):1. 包含。將模板中的相同部分提取出來(lái)共用??梢允褂糜簿幋a的字符串% include foo/bar.html % 或者變量名  % include template_name %,變量當(dāng)然是在view中賦值(注意,不是control

84、ler中)2. 繼承。 模板繼承是django解決共用頁(yè)面區(qū)域dry的一個(gè)優(yōu)雅的解決方案。簡(jiǎn)單地說(shuō)就是先構(gòu)造一個(gè)基礎(chǔ)框架模板,而后在其子模板中對(duì)它所包含站點(diǎn)公用部分和定義塊進(jìn)行重載(override)?;A(chǔ)模板中,將內(nèi)容不同的部分指定各個(gè)內(nèi)容塊:.% block foo %<div>default content of foo</div>% endblock %.% block bar %<div>default content of bar</div>% endblock %.在子模板中指定繼承關(guān)系并override各個(gè)內(nèi)容塊即可。繼

85、承的寫(xiě)法是% extends "base.html" %, 注意一定要放在模板的開(kāi)頭部分。好了,你已經(jīng)理解了django的模板系統(tǒng),下面對(duì)產(chǎn)品清單界面的改造就非常容易理解了。分成兩個(gè)部分:base和productlist。抱歉,寫(xiě)到這里,發(fā)現(xiàn)篇幅已經(jīng)不短了。只好界面的實(shí)現(xiàn)放到下一節(jié)了。django實(shí)戰(zhàn)(7):改造productlist界面有了上一節(jié)關(guān)于django模板的基礎(chǔ),改造界面就很容易理解了。將界面設(shè)計(jì)師設(shè)計(jì)的頁(yè)面中的內(nèi)容根據(jù)復(fù)用程度分別放到基礎(chǔ)模板base.html和專(zhuān)用模板productlist.html中。depot/templates/base.html ht

86、ml view plaincopy1. <html xmlns="/1999/xhtml">  2. <head>  3.     <meta http-equiv="content-type" content="text/html; charset=utf-8">  4.     

87、;<meta name="description" content="a depot implement with django"/>  5.     <meta name="keywords" content="django,depot" />  6.     <meta

88、60;name="author" content="holbrook(7.     <title>% block title % 標(biāo)題 % endblock %</title>  8.     <link rel="stylesheet" href="/static/css/bootstrap.min.css">  9. </head>  10. <body>  11. <div class="container"> 

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論