把數據存取邏輯、業務邏輯和表現邏輯組合在一起的概念有時被稱為軟件架構的 Model-View-Controller (MVC)模式。在這個模式中, Model 代表數據存取層,View 代表的是系統中選擇顯示什么和怎么顯示的部分,Controller 指的是系統中根據用戶輸入並視需要訪問模型,以決定使用哪個視圖的那部分。
由於 C 由框架自行處理,而 Django 里更關注的是模型(Model)、模板(Template)和視圖(Views),Django 也被稱為 MTV 框架 。在 MTV 開發模式中:
M 代表模型(Model),即數據存取層。該層處理與數據相關的所有事務:如何存取、如何確認有效性、包含哪些行為以及數據之間的關系等。
T 代表模板(Template),即表現層。該層處理與表現相關的決定:如何在頁面或其他類型文檔中進行顯示。
V代表View,業務邏輯層。這一層包含訪問模型的邏輯和按照模板顯示。你可以認為它是模型和模板的橋梁。
數據庫配置
修改配置文件 settings.py
DATABASE_ENGINE = '' DATABASE_NAME = '' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_HOST = '' DATABASE_PORT = ''
mysql多實例可以指定用戶
DATABASE_HOST = '/data/3306/mysql.sock'
高版本的Django連接數據庫配置有所不同,參考原版文檔:
如果你只是建造一個簡單的web站點,那么可能你只需要一個app就可以了。如果是復雜的象 電子商務之類的Web站點,你可能需要把這些功能划分成不同的app,以便以后重用。
系統對app有一個約定:如果你使用了Django的數據庫層(模型),你 必須創建一個django app。模型必須在這個app中存在。因此,為了開始建造 我們的模型,我們必須創建一個新的app。
轉到 mysite 項目目錄,執行下面的命令來創建一個新app叫做books:
python manage.py startapp books
在 mysite 目錄下創建了一個 books 的文件夾
books/ __init__.py models.py views.py
創建你的第一個模型
在Django中使用該數據庫布局的第一步是將其表述為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()
每個模型相當於單個數據庫表,每個屬性也是這個表中的一個字段。 屬性名就是字段名,它的類型(例如 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 );
其中:
SERIAL是BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的一個別名。
在整數列定義中,SERIAL DEFAULT VALUE是NOT NULL AUTO_INCREMENT UNIQUE的一個別名。
注:上面NOT NULL是不可為空,AUTO_INCREMENT是遞增,指定起始值為1用AUTO_INCREMENT=1語句,不指定默認也為1。
UNIQE是不可重復的意思,取值不能與已經存在的數據重復。
“每個數據庫表對應一個類”這條規則的例外情況是多對多關系。 在我們的范例模型中, Book 有一個 多對多字段 叫做 authors 。 該字段表明一本書籍有一個或多個作者,但 Book 數據庫表卻並沒有 authors 字段。 相反,Django創建了一個額外的表(多對多連接表)來處理書籍和作者之間的映射關系。
模型安裝
完成這些代碼之后,現在讓我們來在數據庫中創建這些表。要完成該項工作,第一步是在 Django 項目中 激活 這些模型。將 books app 添加到配置文件的已 installed apps 列表中即可完成此步驟。
再次編輯 settings.py 文件, 找到 INSTALLED_APPS 設置。 INSTALLED_APPS 告訴 Django 項目哪些 app 處於激活狀態。缺省情況下如下所示:
MIDDLEWARE_CLASSES = ( # 'django.middleware.common.CommonMiddleware', # 'django.contrib.sessions.middleware.SessionMiddleware', # 'django.contrib.auth.middleware.AuthenticationMiddleware', # 'django.middleware.doc.XViewMiddleware', ) TEMPLATE_CONTEXT_PROCESSORS = () #... INSTALLED_APPS = ( #'django.contrib.auth', #'django.contrib.contenttypes', #'django.contrib.sessions', #'django.contrib.sites', 'mysite.books', )
現在我們可以創建數據庫表了。首先,用下面的命令對校驗模型的有效性:
python manage.py validate
檢查試會報錯:
TypeError: __init__() got an unexpected keyword argument ‘maxlength’
應該是以前的版本是應該用maxlength,但是新版本里面使用max_length
在vim中替換 :%s/maxlength/max_length/g
然后再次報錯:
Error: One or more models did not validate:
books.author: "headshot": To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .
那就開始安裝這個庫:
pip install PIL
DEPRECATION: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of pip will drop support for Python 2.6
Collecting PIL
Could not find a version that satisfies the requirement PIL (from versions: )
No matching distribution found for PIL
只能升級python了
升級到了2.7版本,還是報錯,干脆升級到3.X看看情況:使用souhu的源還是比較快
wget http://mirrors.sohu.com/python/3.3.3/Python-3.3.3.tar.bz2
在編譯前先在/usr/local建一個文件夾python3.3 .3(作為Python的安裝路徑,以免覆蓋老的版本)
mkdir -p /usr/local/python-3.3.3
在解壓縮后的目錄下編譯安裝
./configure --prefix=/usr/local/python-3.3.3
make && make install
將原來/usr/bin/python鏈接改為別的名字
mv /usr/bin/python /usr/bin/python_old
再建立新版本python的鏈接
ln -s /usr/local/python3.3.3/bin/python3 /usr/bin/python
安裝好之后,需要重新安裝setuptools , pip ,MySQLdb, Django
但是經歷了好多,發現對這些的支持都有問題,索性,換一個方法來做:
還是用系統自帶的python2.6.6 , 其他的插件,不用pip來安裝,直接下載先來自己安裝
Imaging-1.1.7
python setup.py install 然后就搞定了
繼續問題前的操作
python manage.py validate
看到 0 errors found 消息,一切正常。繼續:
運行下面的命令來生成 CREATE TABLE 語句:
python manage.py sqlall books
BEGIN; CREATE TABLE `books_publisher` ( `id` integer AUTO_INCREMENT 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` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `salutation` varchar(10) NOT NULL, `first_name` varchar(30) NOT NULL, `last_name` varchar(40) NOT NULL, `email` varchar(75) NOT NULL, `headshot` varchar(100) NOT NULL ) ; CREATE TABLE `books_book` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(100) NOT NULL, `publisher_id` integer NOT NULL, `publication_date` date NOT NULL ) ; ALTER TABLE `books_book` ADD CONSTRAINT `publisher_id_refs_id_4cdc253fc5b274bb` FOREIGN KEY (`publisher_id`) REFERENCES `books_publisher` (`id`); CREATE TABLE `books_book_authors` ( `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `book_id` integer NOT NULL, `author_id` integer NOT NULL, UNIQUE (`book_id`, `author_id`) ) ; ALTER TABLE `books_book_authors` ADD CONSTRAINT `book_id_refs_id_5565ddfcfbcf262` FOREIGN KEY (`book_id`) REFERENCES `books_book` (`id`); ALTER TABLE `books_book_authors` ADD CONSTRAINT `author_id_refs_id_1f0e145e09e7e386` FOREIGN KEY (`author_id`) REFERENCES `books_author` (`id`); CREATE INDEX `books_book_publisher_id` ON `books_book` (`publisher_id`); COMMIT;
sqlall 命令並沒有在數據庫中真正創建數據表,只是把SQL語句段打印出來。運行 syncdb 命令
python manage.py syncdb
Creating table books_publisher Creating table books_book Creating table books_author Installing index for books.Book model
成功創建了表
基本數據訪問
添加一個方法 __unicode__() 到 Publisher 對象。 __unicode__() 方法告訴Python要怎樣把對象unicode的方式顯示出來.
普通的python字符串是經過編碼的,意思就是它們使用了某種編碼方式(如ASCII,ISO-8859-1或者UTF-8)來編碼。
但是Unicode對象並沒有編碼。它們使用Unicode,一個一致的,通用的字符編碼集。 當你在Python中處理Unicode對象的時候,你可以直接將它們混合使用和互相匹配而不必去考慮編碼細節。
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() **def __unicode__(self):** **return self.name** 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' % (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**
>>> from books.models import Publisher >>> p1 = Publisher(name='Addison-Wesley', address='75 Arlington Street', ... city='Boston', state_province='MA', country='U.S.A.', ... website='http://www.apress.com/') >>> p1.save() >>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.', ... city='Cambridge', state_province='MA', country='U.S.A.', ... website='http://www.oreilly.com/') >>> p2.save() >>> publisher_list = Publisher.objects.all() >>> publisher_list
[<Publisher: Addison-Wesley>, <Publisher: O'Reilly>]
所有的數據庫查找都遵循一個通用模式:調用模型的管理器來查找數據。
數據過濾
如果想要獲得數據的一個子集,我們可以使用 filter() 方法:SQL缺省的 = 操作符是精確匹配的
Publisher.objects.filter(country="U.S.A.", state_province="CA")
這個 __contains 部分會被Django轉換成 LIKE SQL語句
Publisher.objects.filter(name__contains="press")
等同於:
SELECT id, name, address, city, state_province, country, website FROM book_publisher WHERE name LIKE '%press%';
獲取單個對象
使用 get() 方法:
Publisher.objects.get(name="Apress Publishing")
數據排序
用 order_by() 來 排列返回的數據:
Publisher.objects.order_by("name")
還可以指定逆向排序,在前面加一個減號 - 前綴:
Publisher.objects.order_by("-name")
每次都要用 order_by() 顯得有點啰嗦。 大多數時間你通常只會對某些 字段進行排序。在這種情況下,Django讓你可以指定模型的缺省排序方式:
class Publisher(models.Model): name = models.CharField(maxlength=30) address = models.CharField(maxlength=50) city = models.CharField(maxlength=60) state_province = models.CharField(maxlength=30) country = models.CharField(maxlength=50) website = models.URLField() def __str__(self): return self.name class Meta: ordering = ["name"]
這個 ordering = ["name"] 告訴Django如果沒有顯示提供 order_by() , 就缺省按名稱排序。
可以同時做這 過濾和排序
Publisher.objects.filter(country="U.S.A.").order_by("-name")
限制返回的數據
只想顯示第一個
Publisher.objects.all()[0]
刪除對象
調用對象的 delete() 方法:
p = Publisher.objects.get(name="Addison-Wesley") p.delete()
后邊的數據庫操作比較繁瑣,就等用的時候再學習更新吧
一個project包含很多個Django app以及對它們的配置。
技術上,project的作用是提供配置文件,比方說哪里定義數據庫連接信息, 安裝的app列表, TEMPLATE_DIRS,等等。
一個app是一套Django功能的集合,通常包括模型和視圖,按Python的包結構的方式存在。
例如,Django本身內建有一些app,例如注釋系統和自動管理界面。 app的一個關鍵點是它們是很容易移植到其他project和被多個project復用。