Django基礎[Python+Django]_第1頁
Django基礎[Python+Django]_第2頁
Django基礎[Python+Django]_第3頁
Django基礎[Python+Django]_第4頁
Django基礎[Python+Django]_第5頁
已閱讀5頁,還剩29頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、中北大學 由Yubg整理 QQ: 120487362第五章 模型在第三章,我們講述了用 Django 建造網站的基本途徑: 建立視圖和 URLConf 。 正如我們所闡述的,視圖負責處理一些主觀邏輯,然后返回響應結果。 作為例子之一,我們的主觀邏輯是要計算當前的日期和時間。在當代 Web 應用中,主觀邏輯經常牽涉到與數據庫的交互。 數據庫驅動網站 在后臺連接數據庫服務器,從中取出一些數據,然后在 Web 頁面用漂亮的格式展示這些數據。 這個網站也可能會向訪問者提供修改數據庫數據的方法。許多復雜的網站都提供了以上兩個功能的某種結合。 例如 A 就是一個數據庫驅動站點的良好范例。 本質上,每個產品

2、頁面都是數據庫中數據以 HTML格式進行的展現,而當你發表客戶評論時,該評論被插入評論數據庫中。由于先天具備 Python 簡單而強大的數據庫查詢執行方法,Django 非常適合開發數據庫驅動網站。 本章深入介紹了該功能: Django 數據庫層。(注意: 盡管對 Django 數據庫層的使用中并不特別強調這點,但是我們還是強烈建議您掌握一些數據庫和 SQL 原理。 對這些概念的介紹超越了本書的范圍,但就算你是數據庫方面的菜鳥,我們也建議你繼續閱讀。 你也許能夠跟上進度,并在上下文學習過程中掌握一些概念。)在視圖中進行數據庫查詢的笨方法正如第三章詳細介紹的那個在視圖中輸出 HTML 的笨方法(

3、通過在視圖里對文本直接硬編碼HTML),在視圖中也有笨方法可以從數據庫中獲取數據。很簡單: 用現有的任何 Python 類庫執行一條 SQL 查詢并對結果進行一些處理。在本例的視圖中,我們使用了 MySQLdb 類庫(可以從 獲得)來連接 MySQL 數據庫,取回一些記錄,將它們提供給模板以顯示一個網頁:from django.shortcuts import render_to_responseimport MySQLdbdef book_list(request):db = MySQLdb.connect(user='me', db='mydb', pass

4、wd='secret', host='localhost')cursor = db.cursor()cursor.execute('SELECT name FROM books ORDER BY name')names = row0 for row in cursor.fetchall()db.close()return render_to_response('book_list.html', 'names': names)這個方法可用,但很快一些問題將出現在你面前:§ 我們將數據庫連接參數硬行編碼于代碼

5、之中。 理想情況下,這些參數應當保存在 Django 配置中。§ 我們不得不重復同樣的代碼: 創建數據庫連接、創建數據庫游標、執行某個語句、然后關閉數據庫。 理想情況下,我們所需要應該只是指定所需的結果。§ 它把我們栓死在 MySQL 之上。 如果過段時間,我們要從 MySQL 換到 PostgreSQL,就不得不使用不同的數據庫適配器(例如 psycopg 而不是 MySQLdb ),改變連接參數,根據 SQL 語句的類型可能還要修改SQL 。 理想情況下,應對所使用的數據庫服務器進行抽象,這樣一來只在一處修改即可變換數據庫服務器。 (如果你正在建立一個開源的Django

6、應用程序來盡可能讓更多人使用的話,這個特性是非常適當的。)正如你所期待的,Django數據庫層正是致力于解決這些問題。 以下提前揭示了如何使用 Django 數據庫 API 重寫之前那個視圖。from django.shortcuts import render_to_responsefrom mysite.books.models import Bookdef book_list(request):books = Book.objects.order_by('name')return render_to_response('book_list.html', &

7、#39;books': books)我們將在本章稍后的地方解釋這段代碼。 目前而言,僅需對它有個大致的認識。MTV 開發模式在鉆研更多代碼之前,讓我們先花點時間考慮下 Django 數據驅動 Web 應用的總體設計。我們在前面章節提到過,Django 的設計鼓勵松耦合及對應用程序中不同部分的嚴格分割。 遵循這個理念的話,要想修改應用的某部分而不影響其它部分就比較容易了。 在視圖函數中,我們已經討論了通過模板系統把業務邏輯和表現邏輯分隔開的重要性。 在數據庫層中,我們對數據訪問邏輯也應用了同樣的理念。把數據存取邏輯、業務邏輯和表現邏輯組合在一起的概念有時被稱為軟件架構的 Model-Vi

8、ew-Controller (MVC)模式。 在這個模式中, Model 代表數據存取層,View 代表的是系統中選擇顯示什么和怎么顯示的部分,Controller 指的是系統中根據用戶輸入并視需要訪問模型,以決定使用哪個視圖的那部分。為什么用縮寫?像 MVC 這樣的明確定義模式的主要用于改善開發人員之間的溝通。 比起告訴同事,“讓我們采用抽象的數據存取方式,然后單獨劃分一層來顯示數據,并且在中間加上一個控制它的層”,一個通用的說法會讓你收益,你只需要說:“我們在這里使用MVC模式吧。”。Django 緊緊地遵循這種 MVC 模式,可以稱得上是一種 MVC 框架。 以下是 Django 中 M

9、、V 和 C 各自的含義:§ M ,數據存取部分,由django數據庫層處理,本章要講述的內容。§ V ,選擇顯示哪些數據要顯示以及怎樣顯示的部分,由視圖和模板處理。§ C ,根據用戶輸入委派視圖的部分,由 Django 框架根據 URLconf 設置,對給定 URL 調用適當的 Python 函數。由于 C 由框架自行處理,而 Django 里更關注的是模型(Model)、模板(Template)和視圖(Views),Django 也被稱為 MTV 框架 。在 MTV 開發模式中:§ M 代表模型(Model),即數據存取層。 該層處理與數據相關的所有

10、事務: 如何存取、如何驗證有效性、包含哪些行為以及數據之間的關系等。§ T 代表模板(Template),即表現層。 該層處理與表現相關的決定: 如何在頁面或其他類型文檔中進行顯示。§ V 代表視圖(View),即業務邏輯層。 該層包含存取模型及調取恰當模板的相關邏輯。 你可以把它看作模型與模板之間的橋梁。如果你熟悉其它的 MVC Web開發框架,比方說 Ruby on Rails,你可能會認為 Django 視圖是控制器,而 Django 模板是視圖。 很不幸,這是對 MVC 不同詮釋所引起的錯誤認識。 在 Django 對 MVC 的詮釋中,視圖用來描述要展現給用戶的數

11、據;不是數據 如何展現 ,而且展現 哪些 數據。 相比之下,Ruby on Rails 及一些同類框架提倡控制器負責決定向用戶展現哪些數據,而視圖則僅決定 如何 展現數據,而不是展現 哪些 數據。兩種詮釋中沒有哪個更加正確一些。 重要的是要理解底層概念。數據庫配置記住這些理念之后,讓我們來開始 Django 數據庫層的探索。 首先,我們需要做些初始配置;我們需要告訴Django使用什么數據庫以及如何連接數據庫。我們假定你已經完成了數據庫服務器的安裝和激活,并且已經在其中創建了數據庫(例如,用 CREATEDATABASE 語句)。 如果你使用SQLite,不需要這步安裝,因為SQLite使用文

12、件系統上的獨立文件來存儲數據。象前面章節提到的 TEMPLATE_DIRS 一樣,數據庫配置也是在Django的配置文件里,缺省是 settings.py 。 打開這個文件并查找數據庫配置:DATABASE_ENGINE = ''DATABASE_NAME = ''DATABASE_USER = ''DATABASE_PASSWORD = ''DATABASE_HOST = ''DATABASE_PORT = ''配置綱要如下。DATABASE_ENGINE告訴Django使用哪個數據庫引擎。如果你

13、在 Django 中使用數據庫,DATABASE_ENGINE必須是 Table 5-1 中所列出的值。表 5-1. 數據庫引擎設置設置數據庫所需適配器 postgresqlPostgreSQLpsycopg 1.x版, postgresql_psycopg2PostgreSQLpsycopg 2.x版, mysqlMySQLMySQLdb ,sqlite3SQLite如果使用Python2.5+則不需要適配器。否則就使用 pysqlite , oracleOraclecx_Oracle ,要注意的是無論選擇使用哪個數據庫服務器,都必須下載和安裝對應的數據庫適配器。訪問表 5-1 中“所需適配

14、器”一欄中的鏈接,可通過互聯網免費獲取這些適配器。如果你使用Linux,你的發布包管理系統會提供合適的包。比如說查找 python-postgresql 或者 python-psycopg 的軟件包。配置示例:DATABASE_ENGINE = 'postgresql_psycopg2'DATABASE_NAME將數據庫名稱告知 Django 。例如:DATABASE_NAME = 'mydb'如果使用 SQLite,請對數據庫文件指定完整的文件系統路徑。例如:DATABASE_NAME = '/home/django/mydata.db'在這個

15、例子中,我們將SQLite數據庫放在/home/django目錄下,你可以任意選用最合適你的目錄。DATABASE_USER告訴 Django 用哪個用戶連接數據庫。例如:如果用SQLite,空白即可。DATABASE_PASSWORD告訴Django連接用戶的密碼。 SQLite 用空密碼即可。DATABASE_HOST告訴 Django 連接哪一臺主機的數據庫服務器。如果數據庫與 Django 安裝于同一臺計算機(即本機),可將此項保留空白。如果你使用SQLite,此項留空。此處的 MySQL 是一個特例。如果使用的是 MySQL 且該項設置值由斜杠('/')開頭,MySQ

16、L 將通過 Unix socket 來連接指定的套接字,例如:DATABASE_HOST = '/var/run/mysql'一旦在輸入了那些設置并保存之后應當測試一下你的配置。 我們可以在 mysite 項目目錄下執行上章所提到的 python manage.py shell 來進行測試。 (我們上一章提到過在, manager.py shell 命令是以正確Django配置啟用Python交互解釋器的一種方法。 這個方法在這里是很有必要的,因為Django需要知道加載哪個配置文件來獲取數據庫連接信息。)輸入下面這些命令來測試你的數據庫配置:>>>from

17、django.db import connection>>>cursor = connection.cursor()如果沒有顯示什么錯誤信息,那么你的數據庫配置是正確的。 否則,你就得 查看錯誤信息來糾正錯誤。 表 5-2 是一些常見錯誤。表 5-2. 數據庫配置錯誤信息錯誤信息解決方法You havent set the DATABASE_ENGINE setting yet.不要以空字符串配置 DATABASE_ENGINE 的值。 表格 5-1 列出可用的值。Environment variable DJANGO_SETTINGS_MODULE is undefined

18、.使用 python manager.py shell 命令啟動交互解釋器,不要以 python 命令直接啟動交互解釋器。Error loading _ module: No module named _.未安裝合適的數據庫適配器 (例如, psycopg 或 MySQLdb )。Django并不自帶適配器,所以你得自己下載安裝。_ isnt an available database backend.把DATABASE_ENGINE 配置成前面提到的合法的數據庫引擎。 也許是拼寫錯誤?database _ does not exist設置 DATABASE_NAME 指向存在的數據庫,或者先

19、在數據庫客戶端中執行合適的 CREATE DATABASE 語句創建數據庫。role _ does not exist設置 DATABASE_USER 指向存在的用戶,或者先在數據庫客戶端中執創建用戶。could not connect to server查看DATABASE_HOST和DATABASE_PORT是否已正確配置,并確認數據庫服務器是否已正常運行。第一個應用程序你現在已經確認數據庫連接正常工作了,讓我們來創建一個 Django app-一個包含模型,視圖和Django代碼,并且形式為獨立Python包的完整Django應用。在這里要先解釋一些術語,初學者可能會混淆它們。 在第二章

20、我們已經創建了 project , 那么 project 和 app 之間到底有什么不同呢?它們的區別就是一個是配置另一個是代碼:一個project包含很多個Django app以及對它們的配置。技術上,project的作用是提供配置文件,比方說哪里定義數據庫連接信息, 安裝的app列表,TEMPLATE_DIRS,等等。一個app是一套Django功能的集合,通常包括模型和視圖,按Python的包結構的方式存在。例如,Django本身內建有一些app,例如注釋系統和自動管理界面。app的一個關鍵點是它們是很容易移植到其他project和被多個project復用。對于如何架構Django代碼并

21、沒有快速成套的規則。 如果你只是建造一個簡單的Web站點,那么可能你只需要一個app就可以了; 但如果是一個包含許多不相關的模塊的復雜的網站,例如電子商務和社區之類的站點,那么你可能需要把這些模塊劃分成不同的app,以便以后復用。不錯,你可以不用創建app,這一點應經被我們之前編寫的視圖函數的例子證明了 。 在那些例子中,我們只是簡單的創建了一個稱為views.py的文件,編寫了一些函數并在URLconf中設置了各個函數的映射。這些情況都不需要使用apps。但是,系統對app有一個約定: 如果你使用了Django的數據庫層(模型),你必須創建一個Django app。 模型必須存放在apps中

22、。 因此,為了開始建造我們的模型,我們必須創建一個新的app。在 mysite 項目文件下輸入下面的命令來創建 books app:python manage.py startapp books這個命令并沒有輸出什么,它只在 mysite 的目錄里創建了一個 books 目錄。 讓我們來看看這個目錄的內容:books/ _init_.py models.py tests.pyviews.pyadmin.py這個目錄包含了這個app的模型和視圖。使用你最喜歡的文本編輯器查看一下 models.py 和 views.py 文件的內容。 它們都是空的,除了 models.py 里有一個 import

23、。這就是你Django app的基礎。在Python代碼里定義模型我們早些時候談到。MTV里的M代表模型。 Django模型是用Python代碼形式表述的數據在數據庫中的定義。 對數據層來說它等同于 CREATE TABLE 語句,只不過執行的是Python代碼而不是 SQL,而且還包含了比數據庫字段定義更多的含義。 Django用模型在后臺執行SQL代碼并把結果用Python的數據結構來描述。 Django也使用模型來呈現SQL無法處理的高級概念。如果你對數據庫很熟悉,你可能馬上就會想到,用Python 和 SQL來定義數據模型是不是有點多余? Django這樣做是有下面幾個原因的:自身(運

24、行時自動識別數據庫)會導致過載和有數據完整性問題。為了提供方便的數據訪問API, Django需要以某種方式知道數據庫層內部信息,有兩種實現方式。第一種方式是用Python明確地定義數據模型,第二種方式是通過自身來自動偵測識別數據模型。第二種方式看起來更清晰,因為數據表信息只存放在一個地方-數據庫里,但是會帶來一些問題。首先,運行時掃描數據庫會帶來嚴重的系統過載。如果每個請求都要掃描數據庫的表結構,或者即便是服務啟動時做一次都是會帶來不能接受的系統過載。(有人認為這個程度的系統過載是可以接受的,而Django開發者的目標是盡可能地降低框架的系統過載)。第二,某些數據庫,尤其是老版本的MySQL

25、,并未完整存儲那些精確的自身元數據。編寫Python代碼是非常有趣的,保持用Python的方式思考會避免你的大腦在不同領域來回切換。盡可能的保持在單一的編程環境/思想狀態下可以幫助你提高生產率。不得不去重復寫SQL,再寫Python代碼,再寫SQL,會讓你頭都要裂了。把數據模型用代碼的方式表述來讓你可以容易對它們進行版本控制。這樣,你可以很容易了解數據層的變動情況。SQL只能描述特定類型的數據字段。例如,大多數數據庫都沒有專用的字段類型來描述Email地址、URL。而用Django的模型可以做到這一點。好處就是高級的數據類型帶來更高的效率和更好的代碼復用。SQL還有在不同數據庫平臺的兼容性問題

26、。發布Web應用的時候,使用Python模塊描述數據庫結構信息可以避免為MySQL, PostgreSQL, and SQLite編寫不同的CREATETABLE。當然,這個方法也有一個缺點,就是Python代碼和數據庫表的同步問題。 如果你修改了一個Django模型, 你要自己來修改數據庫來保證和模型同步。 我們將在稍后講解解決這個問題的幾種策略。最后,我們要提醒你Django提供了實用工具來從現有的數據庫表中自動掃描生成模型。 這對已有的數據庫來說是非常快捷有用的。 我們將在第18章中對此進行討論。第一個模型在本章和后續章節里,我們把注意力放在一個基本的 書籍/作者/出版商 數據庫結構上。

27、 我們這樣做是因為 這是一個眾所周知的例子,很多SQL有關的書籍也常用這個舉例。 你現在看的這本書也是由作者 創作再由出版商出版的哦!我們來假定下面的這些概念、字段和關系:§ 一個作者有姓,有名及email地址。§ 出版商有名稱,地址,所在城市、省,國家,網站。§ 書籍有書名和出版日期。 它有一個或多個作者(和作者是多對多的關聯關系many-to-many), 只有一個出版商(和出版商是一對多的關聯關系one-to-many,也被稱作外鍵foreign key)第一步是用Python代碼來描述它們。 打開由 startapp 命令創建的models.py 并輸入下

28、面的內容:from django.db import modelsclass 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()cla

29、ss 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_dat

30、e = models.DateField()讓我們來快速講解一下這些代碼的含義。 首先要注意的是每個數據模型都是 django.db.models.Model 的子類。它的父類 Model 包含了所有必要的和數據庫交互的方法,并提供了一個簡潔漂亮的定義數據庫字段的語法。 信不信由你,這些就是我們需要編寫的通過Django存取基本數據的所有代碼。每個模型相當于單個數據庫表,每個屬性也是這個表中的一個字段。屬性名就是字段名,它的類型(例如 CharField )相當于數據庫的字段類型 (例如 varchar )。例如, Publisher 模塊等同于下面這張表(用PostgreSQL的 CREAT

31、ETABLE 語法描述):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)

32、 NOT NULL, "website" varchar(200) NOT NULL);事實上,正如過一會兒我們所要展示的,Django 可以自動生成這些 CREATETABLE 語句。“每個數據庫表對應一個類”這條規則的例外情況是多對多關系。 在我們的范例模型中, Book 有一個 多對多字段 叫做 authors。 該字段表明一本書籍有一個或多個作者,但 Book數據庫表卻并沒有 authors 字段。相反,Django創建了一個額外的表(多對多連接表)來處理書籍和作者之間的映射關系。請查看附錄 B 了解所有的字段類型和模型語法選項需要查閱.。最后需要注意的是,我們并沒

33、有顯式地為這些模型定義任何主鍵。除非你單獨指明,否則Django會自動為每個模型生成一個自增長的整數主鍵字段每個Django模型都要求有單獨的主鍵id。模型安裝完成這些代碼之后,現在讓我們來在數據庫中創建這些表。 要完成該項工作,第一步是在 Django 項目中 激活 這些模型。 將 books app 添加到配置文件的已安裝應用列表中即可完成此步驟。再次編輯 settings.py 文件,找到 INSTALLED_APPS 設置。INSTALLED_APPS 告訴 Django 項目哪些 app 處于激活狀態。 缺省情況下如下所示:INSTALLED_APPS = ( 'django

34、.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites',)把這四個設置前面加#臨時注釋起來。 (這四個app是經常使用到的,我們將在后續章節里討論如何使用它們)。同時,注釋掉MIDDLEWARE_CLASSES的默認設置條目,因為這些條目是依賴于剛才我們剛在INSTALLED_APPS注釋掉的apps。 然后,添加 mysite.books 到 INSTALLED_APPS 的末尾,此時設置的內容看起來

35、應該是這樣的:MIDDLEWARE_CLASSES = ( # 'mon.CommonMiddleware', # 'django.contrib.sessions.middleware.SessionMiddleware', # 'django.contrib.auth.middleware.AuthenticationMiddleware',)INSTALLED_APPS = ( # 'django.contrib.auth', # 'django.contrib.contenttypes', # 'd

36、jango.contrib.sessions', # 'django.contrib.sites', 'books',)(就像我們在上一章設置TEMPLATE_DIRS所提到的逗號,同樣在INSTALLED_APPS的末尾也需添加一個逗號,因為這是個單元素的元組。另外,本書的作者喜歡在 每一個 tuple元素后面加一個逗號,不管它是不是只有一個元素。這是為了避免忘了加逗號,而且也沒什么壞處。)現在我們可以創建數據庫表了。 首先,用下面的命令驗證模型的有效性:python manage.py validatevalidate 命令檢查你的模型的語法和邏輯是

37、否正確。 如果一切正常,你會看到 0errorsfound 消息。如果出錯,請檢查你輸入的模型代碼。 錯誤輸出會給出非常有用的錯誤信息來幫助你修正你的模型。一旦你覺得你的模型可能有問題,運行 pythonmanage.pyvalidate 。它可以幫助你捕獲一些常見的模型定義錯誤。模型確認沒問題了,運行下面的命令來生成 CREATETABLE 語句(如果你使用的是Unix,那么可以啟用語法高亮):python manage.py sqlall books在這個命令行中, books 是app的名稱。 和你運行 manage.pystartapp 中的一樣。執行之后,輸出如下:BEGIN;CRE

38、ATE 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, "

39、;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&qu

40、ot; 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" ( "i

41、d" 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

42、", "author_id");CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id");COMMIT;注意:§ 自動生成的表名是app名稱( books )和模型的小寫名稱 ( publisher , book , author )的組合。你可以參考附錄B重寫這個規則需要查閱。§ 我們前面已經提到,Django為每個表格自動添加了一個 id 主鍵,你可以重新設置它。§ 按約定,Django

43、添加 "_id" 后綴到外鍵字段名。你猜對了,這個同樣是可以自定義的。§ 外鍵是用 REFERENCES 語句明確定義的。§ 這些 CREATETABLE 語句會根據你的數據庫而作調整,這樣象數據庫特定的一些字段例如:(MySQL),auto_increment(PostgreSQL),serial(SQLite),都會自動生成。Integerprimarykey 同樣的,字段名稱也是自動處理(例如單引號還好是雙引號)。例子中的輸出是基于PostgreSQL語法的。sqlall 命令并沒有在數據庫中真正創建數據表,只是把SQL語句段打印出來,這樣你可以看

44、到Django究竟會做些什么。如果你想這么做的話,你可以把那些SQL語句復制到你的數據庫客戶端執行,或者通過Unix管道直接進行操作(例如, python manager.py sqlall books | psql mydb )。不過,Django提供了一種更為簡易的提交SQL語句至數據庫的方法: syncdb 命令python manage.py syncdb執行這個命令后,將看到類似以下的內容:Creating table books_publisherCreating table books_authorCreating table books_bookInstalling index

45、 for books.Book modelsyncdb 命令是同步你的模型到數據庫的一個簡單方法。 它會根據 INSTALLED_APPS 里設置的app來檢查數據庫, 如果表不存在,它就會創建它。 需要注意的是, syncdb 并 不能將模型的修改或刪除同步到數據庫;如果你修改或刪除了一個模型,并想把它提交到數據庫,syncdb并不會做出任何處理。 (更多內容請查看本章最后的“修改數據庫的架構”一段。)如果你再次運行 pythonmanage.pysyncdb,什么也沒發生,因為你沒有添加新的模型或者 添加新的app。因此,運行pythonmanage.pysyncdb總是安全的,因為它不會

46、重復執行SQL語句。如果你有興趣,花點時間用你的SQL客戶端登錄進數據庫服務器看看剛才Django創建的數據表。你可以手動啟動命令行客戶端(例如,執行PostgreSQL的 psql 命令),也可以執行 python manage.py dbshell ,這個命令將依據 DATABASE_SERVER 的里設置自動檢測使用哪種命令行客戶端。常言說,后來者居上。基本數據訪問一旦你創建了模型,Django自動為這些模型提供了高級的Python API。 運行 pythonmanage.pyshell 并輸入下面的內容試試看:>>>from books.models import

47、Publisher>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',. city='Berkeley', state_province='CA', country='U.S.A.',. website='>>>p1.save()>>> p2 = Publisher(name="O'Reilly", address='10 Fawcett

48、St.',. city='Cambridge', state_province='MA', country='U.S.A.',. website='>>>p2.save()>>> publisher_list = Publisher.objects.all()>>> publisher_list<Publisher: Publisher object>, <Publisher: Publisher object>這短短幾行代碼干了不少的事。 這里簡單的說

49、一下:§ 首先,導入Publisher模型類, 通過這個類我們可以與包含 出版社 的數據表進行交互。§ 接著,創建一個 Publisher 類的實例并設置了字段 name, address 等的值。§ 調用該對象的 save() 方法,將對象保存到數據庫中。 Django 會在后臺執行一條 INSERT 語句。§ 最后,使用 Publisher.objects 屬性從數據庫取出出版商的信息,這個屬性可以認為是包含出版商的記錄集。 這個屬性有許多方法, 這里先介紹調用 Publisher.objects.all() 方法獲取數據庫中 Publisher 類

50、的所有對象。這個操作的幕后,Django執行了一條SQL SELECT 語句。這里有一個值得注意的地方,在這個例子可能并未清晰地展示。當你使用Django modle API創建對象時Django并未將對象保存至數據庫內,除非你調用 save() 方法:p1 = Publisher(.)# At this point, p1 is not saved to the database yet!p1.save()# Now it is.如果需要一步完成對象的創建與存儲至數據庫,就使用 objects.create() 方法。 下面的例子與之前的例子等價:>>> p1 = Publ

51、isher.objects.create(name='Apress',. address='2855 Telegraph Avenue',. city='Berkeley', state_province='CA', country='U.S.A.',. website='>>> p2 = Publisher.objects.create(name="O'Reilly",. address='10 Fawcett St.', city='

52、Cambridge',. state_province='MA', country='U.S.A.',. website='>>> publisher_list = Publisher.objects.all()>>> publisher_list當然,你肯定想執行更多的Django數據庫API試試看,不過,還是讓我們先解決一點煩人的小問題。添加模塊的字符串表現當我們打印整個publisher列表時,我們沒有得到想要的有用信息,無法把對象區分開來:System Message: WARNING/2 (<s

53、tring>, line 872); backlinkInline literal start-string without end-string.System Message: WARNING/2 (<string>, line 872); backlinkInline literal start-string without end-string.<Publisher: Publisher object>, <Publisher: Publisher object>我們可以簡單解決這個問題,只需要為Publisher 對象添加一個方法 _unico

54、de_() 。 _unicode_() 方法告訴Python如何將對象以unicode的方式顯示出來。 為以上三個模型添加_unicode_()方法后,就可以看到效果了:from django.db import modelsclass 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_l

55、ength=30)country = models.CharField(max_length=50)website = models.URLField()def _unicode_(self):return class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40)email = models.EmailField()def _unicode_(self):return u'%s %s'

56、% (self.first_name, self.last_name)class Book(models.Model):title = models.CharField(max_length=100)authors = models.ManyToManyField(Author)publisher = models.ForeignKey(Publisher) publication_date = models.DateField()def _unicode_(self):return self.title就象你看到的一樣, _unicode_() 方法可以進行任何處理來返回對一個對象的字符串表

57、示。 Publisher和Book對象的_unicode_()方法簡單地返回各自的名稱和標題,Author對象的_unicode_()方法則稍微復雜一些,它將first_name和last_name字段值以空格連接后再返回。對_unicode_()的唯一要求就是它要返回一個unicode對象,如果 _unicode_() 方法未返回一個Unicode對象,而返回比如說一個整型數字,那么Python將拋出一個 TypeError 錯誤,并提示:”coercing to Unicode: need string or buffer, int found” 。Unicode對象什么是Unicode對

58、象呢?你可以認為unicode對象就是一個Python字符串,它可以處理上百萬不同類別的字符從古老版本的Latin字符到非Latin字符,再到曲折的引用和艱澀的符號。普通的python字符串是經過編碼的,意思就是它們使用了某種編碼方式(如ASCII,ISO-8859-1或者UTF-8)來編碼。 如果你把奇特的字符(其它任何超出標準128個如0-9和A-Z之類的ASCII字符)保存在一個普通的Python字符串里,你一定要跟蹤你的字符串是用什么編碼的,否則這些奇特的字符可能會在顯示或者打印的時候出現亂碼。 當你嘗試要將用某種編碼保存的數據結合到另外一種編碼的數據中,或者你想要把它顯示在已經假定了某種編碼的程序中的時候,問題就會發生。 我們都已經見到過網頁和郵件被?弄得亂七八糟。 ? 或者其它出現在奇怪位置的字符:這一般來說就是存在編碼問題了。但是Unicode對象并沒有編碼。它們使用Unicode,一個一致的,通用的字符編碼集。 當你在Python中處理

溫馨提示

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

評論

0/150

提交評論