Login  |  繁體中文
感謝您對「自由軟體鑄造場」的支持與愛護,十多年來「自由軟體鑄造場」受中央研究院支持,並在資訊科學研究所以及資訊科技創新研究中心執行,現已完成階段性的任務。 原網站預計持續維運至 2021年底,網站內容基本上不會再更動。本網站由 Denny Huang 備份封存。
也紀念我們永遠的朋友 李士傑先生(Shih-Chieh Ilya Li)。
Previous Issue

Django 簡介(實作篇)

◎ 實做看看吧!

既然前一篇講得這麼興奮,那我們就來實作看看吧。以下會以 FreeBSD 為 OS,來實際操作一遍。作業系統的差異只在安裝 Django 時會不同,因此若你是其他版本的使用者,請自己找找 installation 的方式,相信不會太難的啦。 1. 安裝 Django

其實安裝這個不難,就用最簡單的 ports 安裝

$ cd /usr/ports/www/py-django
$ make install clean

2. 初始設定

先到自己的目錄設置一個 Django 的專用目錄

$ mkdir ~/django

然後利用 Django 的工具來產生一個 project

$ cd ~/django
$ django-admin.py startproject myproject

此時你在看一下目錄,會發現多出 myproject 這個目錄,檔案如下:

myproject/
__init__.py
manage.py
settings.py
urls.py

這些檔案分別代表

* manage.py: 一個可以和這個 Django project 進行各種互動的 command-line 工具
* settings.py: 這個 Django project 的設定檔
* urls.py: 此 Django project 的 URL 設定

做完上一個步驟過後,請先編輯 settings.py 的下列資料 (當然你要先去 SQL 開一個給 Django 用的 Database):

* DATABASE_ENGINE
* DATABASE_NAME
* DATABASE_USER
* DATABASE_PASSWORD

設定好之後就可以馬上將 server 先跑起來看看

$ python manage.py runserver 140.115.50.23:9005

runserver 代表將 server 跑起來,後面可以指定 IP 以及 port,若看到下列訊息,代表有跑成功了

Validating models...
0 errors found.

Starting server on port 9005 with settings module 'myproject.settings'.
Go to https://140.115.50.23:9005/ for Django.
Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).

雖然我們指定了資料庫,但是資料庫裡頭是空的,我們需要先讓 Django 初始化這個資料庫,因此打

$ python manage.py init

若沒有出現任何錯誤訊息,代表成功!

3. 建立模型

還記得上一篇所提到的通訊錄嗎?我們就來實做一個簡易的通訊錄。

這份通訊錄有很多欄位,其中有兩個比較特殊,一個是學號欄 (因為我還在學 XD),我們將它設為 Primary Key;另外一欄則是班別,它會對到另外一個 class (或說 table),是一個 Foreign Key。

但在建立模型之前,我們要先把我們的專案建立 (先前建立的比較像是站台設定,而這邊新增的專案才是我們要寫程式的地方)。

$ python manage.py startapp phonebook

仔細瞧瞧,多了 phonebook/ 這個資料夾,底下的東西有:

phonebook/
__init__.py
models/
__init__.py
phonebook.py
views.py

很明顯地,models 就是我們放模型的資料夾,而 views.py 則是擺上一篇所述,url 所對應的程式。

◎ 模型檔

依照上述的設計,編輯 models/phonebook.py:

from django.core import meta

# Create your models here.

class ClassName(meta.Model):
id = meta.AutoField('ID', primary_key=True)
name = meta.CharField("Class Name", maxlength=10)
def __repr__(self):
return self.name

class Person(meta.Model):
name = meta.CharField("Chinese Name", maxlength=30)
school_num = meta.CharField("Student ID", maxlength=10, primary_key=True)
class_name = meta.ForeignKey(ClassName, verbose_name="class name")
phone = meta.CharField("Phone Number", maxlength=20)
address = meta.CharField("Address", maxlength=100)
birthday = meta.DateField()
email = meta.EmailField()
def __repr__(self):
return self.name

各個欄位所代表的意思應該都很淺顯易懂。admin = meta.Admin()代表在 Django 內附的管理程式要顯示該 model。而注意 class_name 的地方,是使用 meta.ForeignKey來做關聯。

◎ 註冊 Project

雖然我們利用 manage.py 建立了 phonebook 這個 application,但我們還是要在 settings.py 裡頭設定:

INSTALLED_APPS = (
'myproject.phonebook',
)

留意 後面的逗號要留著唷…

這些東西設定好後,可以使用 manage.py 來確認 Django 所產生的 SQL 語法是否正確:

$  python manage.py sql phonebook
BEGIN;
CREATE TABLE `phonebook_classnames` (
`id` mediumint(9) UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(10) NOT NULL
);
CREATE TABLE `phonebook_persons` (
`name` varchar(30) NOT NULL,
`school_num` varchar(10) NOT NULL PRIMARY KEY,
`class_name_id` integer NOT NULL REFERENCES `phonebook_classnames` (`id`),
`phone` varchar(20) NOT NULL,
`address` varchar(100) NOT NULL,
`birthday` date NOT NULL,
`email` varchar(75) NOT NULL
);
COMMIT;

確認過後,就可以讓 Django 去 SQL 當中把這些表單建立

$ python manage.py install phonebook

4. Admin 介面

前面已經將模型都建立起來了,但是在我們繼續下去之前,先中場休息,看看別的東西。

Django 有一套自己的 Admin 介面,可以讓你輕易的操作 Model 的資料,例如新增、修改、刪除等。然而,這個介面並不是預設就有的,要啟動這個介面,首先要修改一些地方:

* 把 "django.contrib.main" 加到 myproject/settings.py 之中的 INSTALLED_APPS
* 執行 python manage.py install admin。這會將 admin 介面所需要的相關 table 建到 SQL 資料庫中
* 編輯 myproject/urls.py,將 "Uncomment this for admin" 的下一行反註解。這樣 URL 對照才會正確。

接著,執行下列指令來新增一個 superuser 給這個 Admin 介面:

python manage.py createsuperuser

接著他會要你輸入使用者名稱、E-mail 地址以及密碼 (兩次)。

現在,把 server 跑起來

python manage.py runserver 140.115.50.23:9005

然後打開你的瀏覽器,到 https://yoursite:9005/admin/ 下,就應該可以看得到 Admin 的登入畫面了。

此時你可能會發現,phonebook 的東西似乎都沒有出現在 admin 介面,為了要讓它出現,我們必須要修改 myproject/phonebook/models.py 這個檔案,在 ClassName 以及 Person 裡頭都加上

class META:
admin = meta.Admin()

接著再看看,應該就會出現在 Admin 介面裡頭了。

5. 設計你的 URL!!

神奇的功能馬上就要開始了!首先,我們從 URL 開始下手。在前面的步驟 "python manage.py startproject myproject" 時,就產生了一個預設的 URLconf 放在 myproject/urls.py,你可以在 myproject/settings.py 裡頭的 ROOT_URLCONF 看到:

ROOT_URLCONF = 'myproject.urls'

其實剛剛我們就已經改過這個檔案了,現在 myproject/urls.py 應該長成這樣:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
# Example:
# (r'^myproject/', include('myproject.apps.foo.urls.foo')),

# Uncomment this for admin:
(r'^admin/', include('django.contrib.admin.urls.admin')),
)

這一行的意思,就是當我 URL 為 https://yoursite:9005/admin/ ,就使用內建的 django.contrib.admin.urls.admin 來處理這個網頁的要求。此時,我們再另外加一行

(r'^pb/', include('myproject.phonebook.urls')),

這行的意思是說,當 URL 為 https://yoursite:9005/pb/ 時,則使用 myproject/phonebook/urls.py 來做為 URL 設定。這樣的好處是,你在 myproject 底下可能還有很多不同的 applications,這樣區分不會將所有 applications 的 URL 設定都混在一個檔裡頭

因此,接下來請在 myproject/phonebook/ 底下建立一個 urls.py 的檔案,並且下列內容放入檔案內:

from django.conf.urls.defaults import *

info_dict = {
'app_label' : 'phonebook',
'module_name' : 'persons',
}

urlpatterns = patterns('',
(r'^$', 'django.views.generic.list_detail.object_list', info_dict),
(r'^(?P\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
(r'^add/$', 'myproject.phonebook.views.create_person')
)

先解釋 patterns 這三行的意義

1. 第一行代表當 URL 為 https://yoursite:9005/pb/ 的時候,則呼叫 django 內建的 object_list 來處理
2. 第二行代表當 URL 為 https://yoursite:9005/pb/這邊是數字/ 的時候,呼叫 django 內建的 object_detail 來處理,並且將 數字 的部份視為 object_id 這個變數傳給 object_detail
3. 第三行代表當 URL 為 https://yoursite:9005/pb/add/ 的時候,則使用自訂的 myproject.phonebook.views.create_person 來處理

◎ 什麼是 django 內建的 object_list 及 object_detail 呢?

你在瀏覽動態網頁時,是否有發現,網頁其實可以分為幾個模式?以電話簿為例,一定有一頁是電話簿列表,而有一頁是某個人詳細的資料;若是換成 Blog 來說,一定也有一頁是 Blog 的列表,而有一頁是 Blog 文章的內容。因此,Django 在此就將這樣的特性抓出來,給設計動態網頁的人一個通用的程式來使用。

當 URL 為 https://yoursite:9005/pb/ 時,我們就設定這一頁就是電話簿列表。當 server 收到這個 request 的時候,對照到 urls.py 就會知道要使用 django.views.generic.list_detail.object_list,而它將所需要的資料處理完之後,會依照 urls.py 上頭定義的 info_dict 去將樣板目錄中的 phonebook/persons_list.html 找出來,將模板填入之後丟回給瀏覽器。

6. 設計樣板

為了先睹為快,我們先不理睬 https://yoursite:9005/pb/add/ 的部份,我們就先將 list 以及 detail 的樣板設計出來,你馬上就可以看出 django 的威力。

首先,編輯 myproject/settings.py,找到 TEMPLATE_DIRS 之後,填入一個目錄做為樣板的根目錄 (下面以我自己的設定為例)

TEMPLATE_DIRS = (
"/home/yychen/django/templates",
)

接著,將目錄建立出來

$ cd /home/yychen/django
$ mkdir templates
$ cd templates
$ mkdir phonebook

建立 templates/phonebook/persons_list.html,並輸入以下內容

{% if object_list %}









{% for object in object_list %}








{% endfor %}
學號 系級 姓名 電話 E-mail 生日

{{ object.school_num }}
{{ object.get_class_name }} {{ object.name }} {{ object.phone }} {{ object.email }} {{ object.birthday }}

{% else %}

No entries...


{% endif %}
Add an entry

同樣的再建立 templates/phonebook/persons_detail.html,並輸入以下內容:

{{ object.name }}




{% if error_message %}

{{ error_message }}

{% endif %}






























姓名 {{ object.name }}
學號 {{ object.school_num }}
班級 {{ object.get_class_name }}
電話 {{ object.phone }}
住址 {{ object.address }}
生日 {{ object.birthday }}
E-mail {{ object.email }}


做到此時,基本上你已經完成了半成品了!請先進入 admin 介面新增一筆資料,接著瀏覽 https://yoursite:9005/pb/ 看看是否有出現,並且點選學號的部份,就可以觀看詳細資料了!

7. 輸入表單

別忘了這邊只是半成品,我們還有新增的部分還沒有做。在輸入表單的部份,一樣有樣板要設計,除此之外,也有程式的部份需要處理。

◎ 程式部份

首先,由於 myproject/phonebook/urls.py 裡頭設定當後面是 add/ 時,用的是 myproject.phonebook.views.create_person,因此我們要編輯 views.py,並且在裡頭加上一個叫做 create_person 的 class。程式碼如下:

# Create your views here.
from django.core.extensions import render_to_response, get_object_or_404
from django.core.template import Context, loader
from django.core import formfields
from django.models.phonebook import persons, classnames
from django.utils.httpwrappers import HttpResponse, HttpResponseRedirect

def create_person(request):
manipulator = persons.AddManipulator()

if request.POST:
new_data = request.POST.copy()
manipulator.do_html2python(new_data)
new_person = manipulator.save(new_data)

return HttpResponseRedirect("/pb/%s/" % request.POST['school_num'])

else:
error = new_data = {}

form = formfields.FormWrapper(manipulator, new_data, error)
return render_to_response('phonebook/create_form', {'form': form})

運作方式是這樣的:當我們第一次進入 https://yoursite:9005/pb/add/ 時,我們要新增一筆資料,由於我們什麼都還沒操作,因此 reuqest.POST 會是空的、沒有東西,此時我們就建立一個 manipulator,並且用 django 的 formwrapper 製造出一個 form 的 object。此時將 template/phonebook/create_form.html 這個樣板呼叫出來,並且將 form 這個物件丟進去攪和攪和,將結果丟回給瀏覽器。

當我們填好各項欄位之後,我們會將這些欄位資料放入 POST 裡頭,又再丟回給 https://yoursite:9005/pb/add/ 這個網址,因此又是同一程式 (即上述的程式) 接收,此時因為有 request.POST 的資料,因此就將 POST 的資料轉到 manipulator 中,當執行到 manipulator.save() 時,就代表資料存入資料庫了。最後,再將 HTTP 的 Response Redirect 到 https://yoursite:9005/pb/剛剛新增的學號/ 過去,亦即可以馬上瀏覽剛剛新增資料的詳細內容了。

◎ Form 的樣板

剩下最後一樣東西,就是 Form 的樣版了。

新增一個檔案 templates/phonebook/create_form.html,並鍵入下面內容:

{% block content %}

Create an entry:




{{ form.name }}


{{ form.school_num }}


{{ form.class_name }}


{{ form.phone }}


{{ form.address }}


{{ form.birthday }}


{{ form.email }}




{% endblock %}

這樣就大功告成了!!

◎ 結語

依照這一份說明文件可以快速的開發出一個簡單的電話簿網站,但是有許多詳細的內容並未提及。若是有更進一步的興趣,請至 Django 官方網站查詢文件。

然而,官方網站雖然有較詳細的文件,筆者在閱讀時,仍然覺得官方的文件不夠詳細,似乎是由許多碎片組合而成,當我需要知道的某一個簡單的用法及原理時(例如 Form 的處理),卻無法迅速的從官方文件中找出來,也許是對這個架構不夠熟析的緣故,但也相對的認為官方的文件不夠周全。

這個架構的出現是令人振奮的,相信用過類似的東西都會有相同的感覺,期許 Django、Ruby on Rails 及 Turbogears 等 web framework 可以儘早成為一個成熟與完整的框架,讓大家開發網頁更為便利。

You may be interested in the following articles:




OSSF Newsletter : 第 95 期 Adobe 釋出開放源碼工具 BlazeDS
Tags: Django,   陳炯廷,   Python,   Web framework,  
Category: Tech Column