模型——數據庫(一)

模型——數據庫(一)

實驗簡介

以前,咱們講述了用 Django 建造網站的基本途徑: 創建視圖和 URLConf 。 正如咱們所闡述的,視圖負責處理一些主觀邏輯,而後返回響應結果。 做爲例子之一,咱們的主觀邏輯是要計算當前的日期和時間。css

在當代Web應用中,主觀邏輯常常牽涉到與數據庫的交互。數據庫驅動網站 在後臺鏈接數據庫服務器,從中取出一些數據,而後在 Web 頁面用漂亮的格式展現這些數據。 這個網站也可能會向訪問者提供修改數據庫數據的方法。html

許多複雜的網站都提供了以上兩個功能的某種結合。 例如 Amazon.com 就是一個數據庫驅動站點的良好範例。 本質上,每一個產品頁面都是數據庫中數據以 HTML格式進行的展示,而當你發表客戶評論時,該評論被插入評論數據庫中。python

因爲先天具有 Python 簡單而強大的數據庫查詢執行方法,Django 很是適合開發數據庫驅動網站。 本章深刻介紹了該功能: Django 數據庫層。mysql

注意: 儘管對 Django 數據庫層的使用並不特別強調這點,可是咱們仍是強烈建議您掌握一些數據庫和 SQL 原理。 對這些概念的介紹超越了本書的範圍,但就算你是數據庫方面的菜鳥,咱們也建議你繼續閱讀。 你也許可以跟上進度,並在學習過程當中掌握一些概念。web

1、數據庫配置

記住這些理念以後,讓咱們來開始 Django 數據庫層的探索。 首先,咱們須要作些初始配置;咱們須要告訴Django使用什麼數據庫以及如何鏈接數據庫。sql

咱們假定你已經完成了數據庫服務器的安裝和激活,而且已經在其中建立了數據庫(例如,用 CREATE DATABASE 語句)。 若是你使用SQLite,不須要這步安裝,由於SQLite使用文件系統上的獨立文件來存儲數據。shell

像前面章節提到的 TEMPLATE_DIRS 同樣,數據庫配置也是在Django的配置文件裏,缺省 是 settings.py 。 打開這個文件並查找數據庫配置:數據庫

7-1-1.png

ENGINE:告訴Django使用哪一個數據庫引擎。 若是你在 Django 中使用數據庫,直接在django.db.backends.後面加上對應的數據庫名,以下:django

設置 數據庫 所需適配器
postgresql PostgreSQL psycopg 1.x版, http://www.djangoproject.com/r/python-pgsql/1/
postgresql_psycopg2 PostgreSQL psycopg 2.x版, http://www.djangoproject.com/r/python-pgsql/
mysql MySQL MySQLdb , http://www.djangoproject.com/r/python-mysql/
sqlite3 SQLite 若是使用Python 2.5+則不須要適配器。 不然就使用 pysqlite , http://www.djangoproject.com/r/python-sqlite/
oracle Oracle cx_Oracle , http://www.djangoproject.com/r/python-oracle/

要注意的是不管選擇使用哪一個數據庫服務器,都必須下載和安裝對應的數據庫適配器。 訪問「所需適配器」一欄中的連接,可經過互聯網免費獲取這些適配器。 若是你使用Linux,你的發佈包管理系統會提供合適的包。 好比說查python-postgresql或者python-psycopg的軟件包。安全

配置示例(mysql):

ENGINE: 'django.db.backends.mysql' 

NAME 將數據庫名稱告知 Django 。 例如:

NAME: 'mydb' 

若是使用 SQLite,請對數據庫文件指定完整的文件系統路徑。 例如:

NAME: '/home/django/mydata.db' 

在這個例子中,咱們將SQLite數據庫放在/home/django目錄下,你能夠任意選用最合適你的目錄。

USER告訴 Django 用哪一個用戶鏈接數據庫。 例如: 若是用SQLite,空白便可。

PASSWORD告訴Django鏈接用戶的密碼。 SQLite 用空密碼便可。

HOST告訴 Django 鏈接哪一臺主機的數據庫服務器。 若是數據庫與 Django 安裝於同一臺計算機(即本機),可將此項保留空白。 若是你使用SQLite,此項留空。

PORT是這個數據庫使用的端口號,對於mysql不填寫的話,默認爲3306;使用sqlite3不填寫。

此處的 MySQL 是一個特例。 若是使用的是 MySQL 且該項設置值由斜槓( '/' )開頭,MySQL 將經過 Unix socket 來鏈接指定的套接字,例如:

HOST: '/var/run/mysql' 

一旦在輸入了那些設置並保存以後應當測試一下你的配置。 咱們能夠在mysite項目目錄下執行上章所提到的python manage.py shell來進行測試。 (咱們上一章提到過在,manager.py shell命令是以正確Django配置啓用Python交互解釋器的一種方法。 這個方法在這裏是頗有必要的,由於Django須要知道加載哪一個配置文件來獲取數據庫鏈接信息。)

輸入下面這些命令來測試你的數據庫配置,以mysql數據庫爲例,首先用sudo service mysql start命令啓動mysql,而後進入數據庫並建立一個mysite數據庫(mysql用戶root密碼爲空,直接回車便可):

$ sudo service mysql start $ mysql -uroot > create database mysite 

配置好settings.py的DATABASES,如上面的圖所示,最後在python manager.py shell中運行下面代碼:

>>> from django.db import connection >>> cursor = connection.cursor() 

若是沒有顯示什麼錯誤信息,那麼你的數據庫配置是正確的。 不然,你就得 查看錯誤信息來糾正錯誤。

2、第一個應用程序

你如今已經確認數據庫鏈接正常工做了,讓咱們來建立一個Django app包含模型,視圖和Django代碼,而且形式爲獨立Python包的完整Django應用。

在這裏要先解釋一些術語,初學者可能會混淆它們。 在第二章咱們已經建立了 project , 那麼 project 和 app 之間到底有什麼不一樣呢?它們的區別就是一個是配置另外一個是 代碼:

一個project包含不少個Django app以及對它們的配置。

技術上,project的做用是提供配置文件,比方說哪裏定義數據庫鏈接信息, 安裝的app列表, TEMPLATE_DIRS ,等等。

一個app是一套Django功能的集合,一般包括模型和視圖,按Python的包結構的方式存在。

例如,Django自己內建有一些app,例如註釋系統和自動管理界面。 app的一個關鍵點是它們很容易移植到其餘project和被多個project複用。

對於如何架構Django代碼並無快速成套的規則。 若是你只是建造一個簡單的Web站點,那麼可能你只須要一個app就能夠了; 但若是是一個包含許多不相關的模塊的複雜的網站,例如電子商務和社區之類的站點,那麼你可能須要把這些模塊劃分紅不一樣的app,以便之後複用。

雖然,你能夠不用建立app,就能使用views,這一點已經被咱們以前編寫的視圖函數的例子證實了 。 在那些例子中,咱們只是簡單的建立了一個稱爲views.py的文件,編寫了一些函數並在URLconf中設置了各個函數的映射。 這些狀況都不須要使用apps。

可是,系統對app有一個約定: 若是你使用了Django的數據庫層(模型),你必須建立一個Django app。 模型必須存放在apps中。 所以,爲了開始建造 咱們的模型,咱們必須建立一個新的app。

在mysite項目文件下輸入下面的命令來建立名叫books的app:

python manage.py startapp books 

這個命令並無輸出什麼,它只在 mysite 的目錄裏建立了一個 books 目錄。 讓咱們來看看這個目錄的內容:

7-1-2.png

這個目錄包含了這個app的模型和視圖。

使用你最喜歡的文本編輯器查看一下models.py和views.py文件的內容。 它們都是空的,除了models.py 裏有一個 import。這就是你Django app的基礎。

3、第一個模型

咱們把注意力放在一個基本的書籍/做者/出版商的數據庫結構上。 咱們這樣作是由於 這是一個衆所周知的例子,不少SQL有關的書籍也經常使用這個舉例。

咱們來假定下面的這些概念、字段和關係:

  • 一個做者有姓,有名及email地址。

  • 出版商有名稱,地址,所在城市、省,國家,網站。

  • 書籍有書名和出版日期。 它有一個或多個做者(和做者是多對多的關聯關係[many-to-many]), 只有一個出版商(和出版商是一對多的關聯關係[one-to-many],也被稱做外鍵[foreign key])

第一步是用Python代碼來描述它們。打開由startapp命令建立的models.py 並輸入下面的內容:

from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() 

讓咱們來快速講解一下這些代碼的含義。 首先要注意的事是每一個數據模型都是django.db.models.Model的子類。它的父類 Model 包含了全部必要的和數據庫交互的方法,並提供了一個簡潔漂亮的定義數據庫字段的語法。 信不信由你,這些就是咱們須要編寫的經過Django存取基本數據的全部代碼。

每一個模型至關於單個數據庫表,每一個屬性也是這個表中的一個字段。 屬性名就是字段名,它的類型(例如 CharField )至關於數據庫的字段類型 (例如 varchar )。例如, Publisher 模塊等同於下面這張表(用PostgreSQL的 CREATE TABLE 語法描述):

CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL ); 

事實上,正如過一下子咱們所要展現的,Django 能夠自動生成這些 CREATE TABLE 語句。

「每一個數據庫表對應一個類」這條規則的例外狀況是多對多關係。 在咱們的範例模型中, Book 有一個 多對多字段 叫作 authors 。 該字段代表一本書籍有一個或多個做者,但 Book 數據庫表卻並無 authors 字段。 相反,Django建立了一個額外的表(多對多鏈接表)來處理書籍和做者之間的映射關係。

更多模型的操做,來自官方文檔

最後須要注意的是,咱們並無顯式地爲這些模型定義任何主鍵。 除非你單獨指明,不然Django會自動爲每一個模型生成一個自增加的整數主鍵字段,每一個Django模型都要求有單獨的主鍵。

1. 模型安裝

完成這些代碼以後,如今讓咱們在數據庫中建立這些表。 要完成該項工做,第一步是在 Django 項目中 激活 這些模型。 將 books app 添加到配置文件的已安裝應用列表中便可完成此步驟。

再次編輯 settings.py 文件, 找到 INSTALLED_APPS 設置。 INSTALLED_APPS 告訴 Django 項目哪些 app 處於激活狀態。 缺省狀況下以下所示:

7-1-3.png

把這四個設置前面加#臨時註釋起來。 (這四個app是常用到的,咱們將在後續章節裏討論如何使用它們)。同時,註釋掉MIDDLEWARE_CLASSES的默認設置條目,由於這些條目是依賴於剛纔咱們剛在INSTALLED_APPS註釋掉的apps。 而後,添加mysite.books 到INSTALLED_APPS的末尾,此時設置的內容看起來應該是這樣的:

7-1-4.png

(就像咱們在上一章設置TEMPLATE_DIRS所提到的逗號,一樣在INSTALLED_APPS的末尾也需添加一個逗號,由於這是個單元素的元組。 另外,本書的做者喜歡在 每個 tuple元素後面加一個逗號,無論它是否是 只有一個元素。 這是爲了不忘了加逗號,並且也沒什麼壞處。)

'mysite.books'指示咱們正在編寫的books app。 INSTALLED_APPS 中的每一個app都使用 Python的路徑描述,包的路徑,用小數點「.」間隔。

如今咱們能夠建立數據庫表了。 首先,用下面的命令驗證模型的有效性:

python manage.py validate 

validate命令檢查你的模型的語法和邏輯是否正確。 若是一切正常,你會看到0 errors found消息。若是出錯,請檢查你輸入的模型代碼。 錯誤輸出會給出很是有用的錯誤信息來幫助你修正你的模型。

一旦你以爲你的模型可能有問題,運行python manage.py validate。 它能夠幫助你捕獲一些常見的模型定義錯誤。

模型確認沒問題了,運行下面的命令來生成 CREATE TABLE 語句(若是你使用的是Unix,那麼能夠啓用語法高亮):

python manage.py sqlall books 

在這個命令行中, books 是app的名稱。 和你運行 manage.py startapp 中的同樣。執行以後,輸出以下:

BEGIN; CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL ) ; CREATE TABLE "books_author" ( "id" serial NOT NULL PRIMARY KEY, "first_name" varchar(30) NOT NULL, "last_name" varchar(40) NOT NULL, "email" varchar(75) NOT NULL ) ; CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(100) NOT NULL, "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED, "publication_date" date NOT NULL ) ; CREATE TABLE "books_book_authors" ( "id" serial NOT NULL PRIMARY KEY, "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED, "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED, UNIQUE ("book_id", "author_id") ) ; CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id"); COMMIT; 

注意:

自動生成的表名是app名稱( books )和模型的小寫名稱 ( publisher , book , author )的組合。 關於Meta類

咱們前面已經提到,Django爲每一個表格自動添加加了一個 id 主鍵, 你能夠從新設置它。

按約定,Django添加 "_id" 後綴到外鍵字段名。 你猜對了,這個一樣是能夠自定義的。

外鍵是用 REFERENCES 語句明肯定義的。

這些 CREATE TABLE 語句會根據你的數據庫而做調整,這樣象數據庫特定的一些字段例如:(MySQL),auto_increment(PostgreSQL),serial(SQLite),都會自動生成。integer primary key 一樣的,字段名稱也是自動處理(例如單引號還好是雙引號)。 例子中的輸出是基於PostgreSQL語法的。

sqlall 命令並無在數據庫中真正建立數據表,只是把SQL語句段打印出來,這樣你能夠看到Django究竟會作些什麼。 若是你想這麼作的話,你能夠把那些SQL語句複製到你的數據庫客戶端執行,或者經過Unix管道直接進行操做(例如, python manager.py sqlall books | psql mydb)。不過,Django提供了一種更爲簡易的提交SQL語句至數據庫的方法:syncdb命令

python manage.py syncdb 

執行這個命令後,將看到相似如下的內容:

Creating table books_publisher
Creating table books_author
Creating table books_book
Installing index for books.Book model 

syncdb命令是同步你的模型到數據庫的一個簡單方法。 它會根據INSTALLED_APPS裏設置的app來檢查數據庫, 若是表不存在,它就會建立它。 須要注意的是, syncdb 並不能將模型的修改或刪除同步到數據庫;若是你修改或刪除了一個模型,並想把它提交到數據庫,syncdb並不會作出任何處理。

若是你再次運行python manage.py syncdb ,什麼也沒發生,由於你沒有添加新的模型或者 添加新的app。所以,運行python manage.py syncdb老是安全的,由於它不會重複執行SQL語句。

若是你有興趣,花點時間用你的SQL客戶端登陸進數據庫服務器看看剛纔Django建立的數據表。 你能夠手動啓動命令行客戶端(例如,執行PostgreSQL的psql命令),也能夠執行 python manage.py dbshell,這個命令將依據DATABASE_SERVER 的裏設置自動檢測使用數據庫命令行客戶端。

4、小結

本節講了模型的一些基本知識和命令, 開啓Django定製的python shell:

python manage.py shell 

在Django項目下建立新的APP:

python manage.py startapp <app-name> 

檢查models的語法:

python manage.py validate 

根據models.py代碼生成相應SQL代碼:

python manage.py sqlall <app-name> 

將上一步的SQL代碼,提交到對應的數據庫:

python manage.py syncdb 

打開對應數據庫的shell:

python manage.py dbshell 

下一節,咱們將知道經過Django來操做數據庫,這都是基礎。

這裏再次提醒你們,必定要去翻看Django對應版本(本課程使用1.4)官方文檔,由於Django在不斷的更新,老版本被開發者所詬病的設計,在1.4+的版本獲得了很大的改善。

Django 1.4 官方文檔, 中國源,部分翻譯

做業

請再新建一個app,建立課程、教師和學生三個模型用於選課,並處理好它們之間的關係。

相關文章
相關標籤/搜索