settings 文件內:python
DATABASES = { ' default ' : { ' ENGINE ' : ' django.db.backends.postgresql_psycopg2 ' , ' NAME ' : ' mydatabase ' , ' USER ' : ' mydatabaseuser ' , ' PASSWORD ' : ' mypassword ' , ' HOST ' : ' 127.0.0.1 ' , ' PORT ' : ' 5432 ' , } }
若是是 SQLite,則只需填寫 engine 和 name,SQLite 的 name 應當包含可靠路徑(由於沒有 server):web
DATABASES = { ' default ' : { ' ENGINE ' : ' django.db.backends.sqlite3 ' , ' NAME ' : ' mydatabase ' , } }
測試數據庫配置:sql
>>> from django.db import connection >>> cursor = connection.cursor()
django 的 ORM 示例,定義在 app 下的 models 文件內,具體支持的字段參考官方文檔:shell
from django.db import models class Book(models.Model): title = models.CharField(max_length = 100 ) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField()
django 使用額外一張單獨的表來管理多對多聯繫。數據庫
在部署模型前,首先應保證相應的 app 是已安裝狀態,這在 settings 文件內的 INSTALLED_APPS 字段內進行設置。django
python manage.py validate
python manage.py sqlall books
這裏的 books 是 app 的名稱。運行後輸出以下:安全
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
python manage.py syncdb
在 python manage.py shell 命令行內執行 INSERT 操做的方法是實例化一個模型對象,並調用其 .save() 方法post
>>> from books.models import Publisher >>> p1 = Publisher(name = ' Apress ' , address = ' 2855 Telegraph Avenue ' , ... city = ' Berkeley ' , state_province = ' CA ' , country = ' U.S.A. ' , ... website = ' http://www.apress.com/ ' ) >>> p1.save()
不過這個 save() 方法在用於 UPDATE 功能時,實際執行的是更新整行而不只是修改過的屬性。這可能會引發競態條件,若是想只更新一個屬性,應當調用結果集的 .update() 方法:測試
>>> Publisher.objects.filter(id = 52 ).update(name = ' Apress Publishing ' )
update() 方法返回一個整數,表示受影響的行數。
.delete() 方法與 .update() 相似,都是做用於結果集的方法。但出於安全考慮,在刪除表中全部元組時,須要顯示調用 .all() 方法:
>>> Publisher.objects.delete() Traceback (most recent call last): File " <console> " , line 1 , in < module > AttributeError: ' Manager ' object has no attribute ' delete ' >>> Publisher.objects.all().delete()
若是想 print 出 Publisher 對象的內容,須要在定義模型時寫好 __str__() 方法。
>>> publisher_list = Publisher.objects.all() >>> publisher_list [ < Publisher: Publisher object > , < Publisher: Publisher object > ]
>>> Publisher.objects.filter(name = ' Apress ' [, *** ]) [ < Publisher: Apress > ]
注意這裏是雙下劃線 __contains
>>> Publisher.objects.filter(name__contains = " press " ) [ < Publisher: Apress > ]
filter() 返回的老是一個容器對象,這個對象實現了列表的操做方法(一如既往不包括負索引),所以老是可使用好比 for 循環來迭代其中的元素。對應的有一個 get() 方法,這個方法要求知足條件的元素有且只有一個,不然引起異常。
>>> Publisher.objects.order_by( " state_province " , " address " )
第二個參數僅在第一個參數相同時起做用,排序還能夠在屬性前加「-」來實現逆序:
>>> Publisher.objects.order_by( " -name " )
.ordered_by() 可做用於結果查詢結果對象集,因此 filter() 返回的結果也能夠支持。
或者,直接在模型定義的地方指定默認排序方式:
class Publisher(models.Model): name = models.CharField(max_length = 30 ) . . . class Meta: ordering = [ ' name ' ]
當訪問外鍵字段時,會獲得相應的模型對象:
>>> b = Book.objects.get(id = 50 ) >>> b.publisher < Publisher: Apress Publishing > >>> b.publisher.website u ' http://www.apress.com/ '
而當經過外鍵反向追溯時,則會得到一個模型對象的 QuerySet,這個對象與前面同樣也支持過濾和分切操做。實現這類訪問使用的屬性名是由模型名稱的小寫 + _set 組成的:
>>> p = Publisher.objects.get(name = ' Apress Publishing ' ) >>> p.book_set.all() [ < Book: The Django Book > , < Book: Dive Into Python > , ...] >>> p.book_set.filter(name__icontains = ' django ' ) [ < Book: The Django Book > , < Book: Pro Django > ]
多對多和外鍵工做方式相同,只不過處理的是QuerySet而不是模型實例:
>>> b = Book.objects.get(id = 50 ) >>> b.authors.all() [ < Author: Adrian Holovaty > , < Author: Jacob Kaplan - Moss > ] >>> b.authors.filter(first_name = ' Adrian ' ) [ < Author: Adrian Holovaty > ] >>> b.authors.filter(first_name = ' Adam ' ) []
反向查詢也能夠。 要查看一個做者的全部書籍,使用author.book_set ,就如這樣:
>>> a = Author.objects.get(first_name = ' Adrian ' , last_name = ' Holovaty ' ) >>> a.book_set.all() [ < Book: The Django Book > , < Book: Adrian ' s Other Book>]
先前提到過,syncdb 命令只添加新表,並不會把已有模型的更新同步到數據庫中。實際上,django 對已有 模型 與 數據庫 之間的對應關係僅做最低限度的檢查——即:模型中的字段在數據庫中必須有,不然會引起運行時錯誤(在用戶進行查詢的時候);至於數據庫中是否存在模型裏並未定義的字段,django 並不關心,由於數據庫中多餘的字段並不影響 django 依據模型作正常的查詢。(django 在作 orm 到 sql 語句的轉化時,老是會明確指出要查詢的字段)
基於這種邏輯,想要修改數據庫模式應該採用的方法就是:在不引起運行時錯誤的前提下,按特定順序分別修改數據庫和模型。具體順序爲:
在形如 Book.objects.all() 的語句中,objects 做爲 models.Model 類的一個特殊屬性,他是 models.Manager 的實例。有些時候咱們能夠經過自定義這個屬性來實現一些特別的方法,或修改 manager 返回的 QuerySets 。
這須要子類化一個 Manager 對象,再把它綁定到具體的模型中,好比:
# models.py from django.db import models # ... Author and Publisher models here ... class BookManager(models.Manager): def title_count(self, keyword): return self.filter(title__icontains = keyword).count() class Book(models.Model): title = models.CharField(max_length = 100 ) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() num_pages = models.IntegerField(blank = True, null = True) objects = BookManager() def __unicode__ (self): return self.title
有了這個manager,咱們如今能夠這樣作:
>>> Book.objects.title_count( ' django ' ) 4 >>> Book.objects.title_count( ' python ' ) 18
manager的基本QuerySet返回系統中的全部對象。 例如,`` Book.objects.all()`` 返回數據庫book中的全部書本。咱們能夠經過覆蓋Manager.get_query_set()方法來重寫manager的基本QuerySet。 get_query_set()按照你的要求返回一個QuerySet。
from django.db import models # First, define the Manager subclass. class DahlBookManager(models.Manager): def get_query_set(self): return super(DahlBookManager, self).get_query_set().filter(author = ' Roald Dahl ' ) # Then hook it into the Book model explicitly. class Book(models.Model): title = models.CharField(max_length = 100 ) author = models.CharField(max_length = 50 ) # ... objects = models.Manager() # The default manager. dahl_objects = DahlBookManager() # The Dahl-specific manager.
在這個示例模型中,Book.objects.all()返回了數據庫中的全部書本,而Book.dahl_objects.all()只返回了Roald Dahl的書。
這個例子也說明了另一件事情,就是一個模型能夠有多個 manager 屬性。你只須要給他們作好命名就能夠了(不要再用 objects)。
注意:django 會把模型中定義的第一個 manager 做爲默認 manager 使用,若是你重寫了任何一個 manager 的話。因此當你給模型添加 manager 的時候,必定記得在最前面把 models.Manager 綁定給 objects 。
模型方法就是模型裏定義的方法,跟普通類裏定義的方法沒什麼不一樣。
使用 DB-API 便可。