Python框架之Django學習筆記(十)

  又是一週週末,如約學習Django框架。在上一次,介紹了MVC開發模式以及Django本身的MVT開發模式,這次,就從數據處理層Model談起。python

  數據庫配置mysql

  首先,咱們須要作些初始配置;咱們須要告訴Django使用什麼數據庫以及如何鏈接數據庫。假定你已經完成了數據庫服務器的安裝和激活,而且已經在其中建立了數據庫(例如,用 CREATE DATABASE語句)。 若是你使用SQLite,不須要這步安裝,由於SQLite使用文件系統上的獨立文件來存儲數據。和前面章節提到的 TEMPLATE_DIRS 同樣,數據庫配置也是在Django的配置文件settings.py 裏。 打開這個文件並查找數據庫配置:  web

1 DATABASES = {
2     'default': {
3         'ENGINE': 'django.db.backends.sqlite3',
4         'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
5     }
6 }

   原始配置如上所示,此爲1.6.6版本的Django配置文件,恩,就是這樣。若有不一樣也不要緊。下面按照以下來配置數據庫信息:  sql

 1 DATABASES = {
 2     'default': {
 3         'ENGINE': 'django.db.backends.mysql',   #數據庫種類
 4         'NAME':'books',                         #數據名稱
 5         'USER':'root',                                      
 6         'PASSWORD':'123456',
 7         'HOST':'127.0.0.1',
 8         'PORT':'3306',
 9     }
10 }    

  配置保存以後,能夠在命令行中進入工程目錄下,如個人是「mysite」下,執行shell

1 python manage.py shell

 

  進入命令行以後再進行測試。輸入如下命令來進行測試: 數據庫

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

 

 若是沒有顯示什麼錯誤信息,那麼恭喜你配置成功,不然,你就要查看錯誤信息來糾正錯誤,下面是一些常見的錯誤:django

 

第一個應用程序服務器

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

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

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

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

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

  對於如何架構Django代碼並無快速成套的規則。 若是你只是建造一個簡單的Web站點,那麼可能你只須要一個app就能夠了; 但若是是一個包含許多不相關的模塊的複雜的網站,例如電子商務和社區之類的站點,那麼你可能須要把這些模塊劃分紅不一樣的app,以便之後複用。不錯,你能夠不用建立app,這一點應經被咱們以前編寫的視圖函數的例子證實了 。 在那些例子中,咱們只是簡單的建立了一個稱爲views.py的文件,編寫了一些函數並在URLconf中設置了各個函數的映射。 這些狀況都不須要使用apps。可是,系統對app有一個約定: 若是你使用了Django的數據庫層(模型),你 必須建立一個Django app。 模型必須存放在apps中。 所以,爲了開始建造 咱們的模型,咱們必須建立一個新的app。

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

1 python manage.py startapp books

 

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

1 books/
2     __init__.py
3     admin.py
4     models.py
5     tests.py
6     views.py

 

  這個目錄包含了這個app的模型和視圖。使用你最喜歡的文本編輯器查看一下 models.py 和 views.py 文件的內容(博主大愛Sublime Text2)。 它們都是空的,除了 models.py 裏有一個 import。這就是你Django app的基礎。

第一個模型

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

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

 1 from django.db import models
 2 
 3 class Publisher(models.Model):
 4     name = models.CharField(max_length=30)
 5     address = models.CharField(max_length=50)
 6     city = models.CharField(max_length=60)
 7     state_province = models.CharField(max_length=30)
 8     country = models.CharField(max_length=50)
 9     website = models.URLField()
10 
11 class Author(models.Model):
12     first_name = models.CharField(max_length=30)
13     last_name = models.CharField(max_length=40)
14     email = models.EmailField()
15 
16 class Book(models.Model):
17     title = models.CharField(max_length=100)
18     authors = models.ManyToManyField(Author)
19     publisher = models.ForeignKey(Publisher)
20     publication_date = models.DateField()

 

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

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

模型安裝

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

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

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

 

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

 1 INSTALLED_APPS = (
 2     'mysite',
 3     'books',
 4     #'django.contrib.admin',
 5     #'django.contrib.auth',
 6     #'django.contrib.contenttypes',
 7     #'django.contrib.sessions',
 8     #'django.contrib.messages',
 9     #'django.contrib.staticfiles',
10 )

 

   PS:就像咱們在上一章設置TEMPLATE_DIRS所提到的逗號,一樣在INSTALLED_APPS的末尾也需添加一個逗號,由於這是個單元素的元組。 另外,本書的做者喜歡在  每個 tuple元素後面加一個逗號,無論它是否是 只有一個元素。 這是爲了不忘了加逗號,並且也沒什麼壞處。
  如今咱們能夠建立數據庫表了。 首先,用下面的命令驗證模型的有效性: 
1 python manage.py validate

   validate 命令檢查你的模型的語法和邏輯是否正確。 若是一切正常,你會看到 0 errors found 消息。若是出錯,請檢查你輸入的模型代碼。 錯誤輸出會給出很是有用的錯誤信息來幫助你修正你的模型。一旦你以爲你的模型可能有問題,運行 python manage.py validate 。 它能夠幫助你捕獲一些常見的模型定義錯誤。模型確認沒問題了,運行下面的命令來生成 CREATE TABLE 語句:

1 python manage.py sqlall books

 

  在這個命令行中,  books 是app的名稱。 和你運行 manage.py startapp 中的同樣。執行以後,輸出以下:
  
 1 BEGIN;
 2 CREATE TABLE "books_publisher" (
 3     "id" serial NOT NULL PRIMARY KEY,
 4     "name" varchar(30) NOT NULL,
 5     "address" varchar(50) NOT NULL,
 6     "city" varchar(60) NOT NULL,
 7     "state_province" varchar(30) NOT NULL,
 8     "country" varchar(50) NOT NULL,
 9     "website" varchar(200) NOT NULL
10 )
11 ;
12 CREATE TABLE "books_author" (
13     "id" serial NOT NULL PRIMARY KEY,
14     "first_name" varchar(30) NOT NULL,
15     "last_name" varchar(40) NOT NULL,
16     "email" varchar(75) NOT NULL
17 )
18 ;
19 CREATE TABLE "books_book" (
20     "id" serial NOT NULL PRIMARY KEY,
21     "title" varchar(100) NOT NULL,
22     "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED,
23     "publication_date" date NOT NULL
24 )
25 ;
26 CREATE TABLE "books_book_authors" (
27     "id" serial NOT NULL PRIMARY KEY,
28     "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED,
29     "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED,
30     UNIQUE ("book_id", "author_id")
31 )
32 ;
33 CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id");
34 COMMIT;

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

1 python manage.py syncdb

 

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

基本數據訪問

  一旦你建立了模型,Django自動爲這些模型提供了高級的Python API。 運行 python manage.py shell 並輸入下面的內容試試看:

 1 >>> from books.models import Publisher
 2 >>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
 3 ...     city='Berkeley', state_province='CA', country='U.S.A.',
 4 ...     website='http://www.apress.com/')
 5 >>> p1.save()
 6 >>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.',
 7 ...     city='Cambridge', state_province='MA', country='U.S.A.',
 8 ...     website='http://www.oreilly.com/')
 9 >>> p2.save()
10 >>> publisher_list = Publisher.objects.all()
11 >>> publisher_list
12 [<Publisher: Publisher object>, <Publisher: Publisher object>]

 

  這短短几行代碼幹了很多的事。 這裏簡單的說一下:

  • 首先,導入Publisher模型類, 經過這個類咱們能夠與包含 出版社 的數據表進行交互。
  • 接着,建立一個`` Publisher`` 類的實例並設置了字段" name, address" 等的值。
  • 調用該對象的 save() 方法,將對象保存到數據庫中。 Django 會在後臺執行一條 INSERT 語句。
  • 最後,使用"Publisher.objects" 屬性從數據庫取出出版商的信息,這個屬性能夠認爲是包含出版商的記錄集。 這個屬性有許多方法, 這裏先介紹調用"Publisher.objects.all()" 方法獲取數據庫中"Publisher" 類的全部對象。這個操做的幕後,Django執行了一條SQL "SELECT" 語句。

  這裏有一個值得注意的地方,在這個例子可能並未清晰地展現。 當你使用Django modle API建立對象時Django並未將對象保存至數據庫內,除非你調用"save()" 方法: 

1 p1 = Publisher(...)
2 # At this point, p1 is not saved to the database yet!
3 p1.save()
4 # Now it i

 

  若是須要一步完成對象的建立與存儲至數據庫,就使用 "objects.create()" 方法。 下面的例子與以前的例子等價:

 1 >>> p1 = Publisher.objects.create(name='Apress',
 2 ...     address='2855 Telegraph Avenue',
 3 ...     city='Berkeley', state_province='CA', country='U.S.A.',
 4 ...     website='http://www.apress.com/')
 5 >>> p2 = Publisher.objects.create(name="O'Reilly",
 6 ...     address='10 Fawcett St.', city='Cambridge',
 7 ...     state_province='MA', country='U.S.A.',
 8 ...     website='http://www.oreilly.com/')
 9 >>> publisher_list = Publisher.objects.all()
10 >>> publisher_list

 

  當咱們打印整個publisher列表時,咱們沒有獲得想要的有用信息。

1 [<Publisher: Publisher object>, <Publisher: Publisher object>]

 

  咱們能夠簡單解決這個問題,只須要爲Publisher 對象添加一個方法 __unicode__() 。 __unicode__() 方法告訴Python如何將對象以unicode的方式顯示出來。 爲以上三個模型添加__unicode__()方法後,就能夠看到效果了:

 1 from django.db import models
 2 
 3 class Publisher(models.Model):
 4     name = models.CharField(max_length=30)
 5     address = models.CharField(max_length=50)
 6     city = models.CharField(max_length=60)
 7     state_province = models.CharField(max_length=30)
 8     country = models.CharField(max_length=50)
 9     website = models.URLField()
10 
11     def __unicode__(self):
12         return self.name
13 
14 class Author(models.Model):
15     first_name = models.CharField(max_length=30)
16     last_name = models.CharField(max_length=40)
17     email = models.EmailField()
18 
19     def __unicode__(self):
20         return u'%s %s' % (self.first_name, self.last_name)
21 
22 class Book(models.Model):
23     title = models.CharField(max_length=100)
24     authors = models.ManyToManyField(Author)
25     publisher = models.ForeignKey(Publisher)
26     publication_date = models.DateField()
27 
28     def __unicode__(self):
29         return self.title

 

  就象你看到的同樣, __unicode__() 方法能夠進行任何處理來返回對一個對象的字符串表示。 PublisherBook對象的__unicode__()方法簡單地返回各自的名稱和標題,Author對象的__unicode__()方法則稍微複雜一些,它將first_namelast_name字段值以空格鏈接後再返回。

  以上就是此次博文的主要內容,to be continued···

相關文章
相關標籤/搜索