上一回說到,姜戈的江湖初體驗:如何架設伺服器,如何回覆http請求,如何建立App。這一回,我們要走入糖果莊園。
資料庫是一所大莊園,藏著各種寶貝。一個沒有資料庫的網站,所能提供的功能會非常有限。
為了找到心愛的人,姜戈決定一探這神祕的糖果莊園。
連線資料庫
Django為多種資料庫後臺提供了統一的呼叫API。根據需求不同,Django可以選擇不同的資料庫後臺。MySQL算是最常用的資料庫。我們這裡將Django和MySQL連線。
在Linux終端下啟動mysql:
1 |
$mysql -u root -p |
在MySQL中創立Django專案的資料庫:
1 |
mysql> CREATE DATABASE villa DEFAULT CHARSET=utf8; |
這裡使用utf8作為預設字符集,以便支援中文。
在MySQL中為Django專案創立使用者,並授予相關許可權:
1 |
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON villa.* TO 'vamei'@'localhost' IDENTIFIED BY 'vameiisgood'; |
在settings.py中,將DATABASES物件更改為:
1 2 3 4 5 6 7 8 9 10 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'villa', 'USER': 'vamei', 'PASSWORD': 'vameiisgood', 'HOST':'localhost', 'PORT':'3306', } } |
後臺型別為mysql。上面包含資料庫名稱和使用者的資訊,它們與MySQL中對應資料庫和使用者的設定相同。Django根據這一設定,與MySQL中相應的資料庫和使用者連線起來。此後,Django就可以在資料庫中讀寫了。
姜戈略一遲疑,旋即走入了莊園的大門。
創立模型
MySQL是關係型資料庫。但在Django的幫助下,我們不用直接編寫SQL語句。Django將關係型的表(table)轉換成為一個類(class)。而每個記錄(record)是該類下的一個物件(object)。我們可以使用基於物件的方法,來操縱關係型的MySQL資料庫。
在傳統的MySQL中,資料模型是表。在Django下,一個表為一個類。表的每一列是該類的一個屬性。在models.py中,我們建立一個只有一列的表,即只有一個屬性的類:
1 2 3 4 5 6 |
from django.db import models class Character(models.Model): name = models.CharField(max_length=200) def __unicode__(self): return self.name |
類Character定義了資料模型,它需要繼承自models.Model。在MySQL中,這個類實際上是一個表。表只有一列,為name。可以看到,name屬性是字元型別,最大長度為200。
類Character有一個__unicode__()方法,用來說明物件的字元表達方式。如果是Python 3,定義__str__()方法,實現相同的功能。
命令Django同步資料庫。Django根據models.py中描述的資料模型,在MySQL中真正的建立各個關係表:
1 |
$python manage.py syncdb |
同步資料庫後,Django將建立相關的MySQL表格,並要求你建立一個超級使用者:
Creating tables …
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table west_character
You just installed Django’s auth system, which means you don’t have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use ‘tommy’): vamei
Email address: vamei@vamei.com
Password:
Password (again):
Superuser created successfully.
Installing custom SQL …
Installing indexes …
Installed 0 object(s) from 0 fixture(s)
資料模型建立了。開啟MySQL命令列:
1 |
$mysql -u vamei -p |
檢視資料模型:
1 2 3 |
USE villa; SHOW TABLES; SHOW COLUMNS FROM west_character; |
最後一個命令返回Character類的對應表格:
+——-+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+——-+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(200) | NO | | NULL | |
+——-+————–+——+—–+———+—————-+
2 rows in set (0.00 sec)
可以看到,Django還自動增加了一個id列,作為記錄的主鍵(Primary Key)。
這富麗堂皇的別墅中,姜戈隱隱聞到凶險的味道。
顯示資料
資料模型雖然建立了,但還沒有資料輸入。為了簡便,我們手動新增記錄。開啟MySQL命令列,並切換到相應資料庫。新增記錄:
1 2 3 |
INSERT INTO west_character (name) Values ('Vamei'); INSERT INTO west_character (name) Values ('Django'); INSERT INTO west_character (name) Values ('John'); |
檢視記錄:
1 |
SELECT * FROM west_character; |
可以看到,三個名字已經錄入資料庫。
下面我們從資料庫中取出資料,並返回給http請求。在west/views.py中,新增檢視。對於對應的請求,我們將從資料庫中讀取所有的記錄,然後返回給客戶端:
1 2 3 4 5 6 7 8 9 10 |
# -*- coding: utf-8 -*- from django.http import HttpResponse from west.models import Character def staff(request): staff_list = Character.objects.all() staff_str = map(str, staff_list) return HttpResponse("" + ' '.join(staff_str) + "") |
可以看到,我們從west.models中引入了Character類。通過操作該類,我們可以讀取表格中的記錄
為了讓http請求能找到上面的程式,在west/urls.py增加url導航:
1 2 3 4 5 |
from django.conf.urls import patterns, include, url urlpatterns = patterns('', url(r'^staff/','west.views.staff'), ) |
執行伺服器。在瀏覽器中輸入URL:
127.0.0.1:8000/west/staff
檢視效果:
從資料庫讀出資料,顯示在頁面
“我心愛的人,原來你在這裡。” 姜戈強自鎮定,嘴角忍不住顫動。
總結
Django使用類和物件介面,來操縱底層的資料庫。
有了資料庫,就有了站點內容的大本營。
姜戈,風雨欲來。