- 創(chuàng)建項目:django-admin.py startproject project_name
python manage.py help 查看所有命令集
-
但是,系統(tǒng)對app有一個約定: 如果你使用了Django的數(shù)據(jù)庫層(模型),你 必須創(chuàng)建一個django app。 模型必須存放在apps中
- python manage.py startapp app_name
用下面的命令對校驗?zāi)P偷挠行裕簆ython manage.py validate
-
sqlall 命令并沒有在數(shù)據(jù)庫中真正創(chuàng)建數(shù)據(jù)表,只是把SQL語句段打印出來: python manage.py sqlall books
執(zhí)行這些SQL語句,運行 syncdb 命令:python manage.py syncdb- syncdb 命令是同步你的模型到數(shù)據(jù)庫的一個簡單方法。它會根據(jù) INSTALLED_APPS 里設(shè)置的app來檢查數(shù)據(jù)庫, 如果表不存在,它就會創(chuàng)建它。
- 需要注意的是, syncdb 并 不能 同步模型的修改到數(shù)據(jù)庫。如果你修改了模型,然后你想更新 數(shù)據(jù)庫, syncdb是幫不了你的
- 如果你再次運行 python manage.py syncdb ,什么也沒發(fā)生,因為你沒有添加新的模型或者 添加新的app
只需要添加一個方法
__str__()到 Publisher 對象。__str__()方法告訴Python要怎樣把對象當(dāng)作字符串來使用__str()__也是一個很好的例子來演示我們怎么添加 行為 到模型里。 Django的模型不只是為對象定義了數(shù)據(jù)庫表的結(jié)構(gòu),還定義了對象的行為。__str__()就是一個例子來演示模型知道怎么顯示它們自己Publisher.objects.all()這行的每個部分:objects 是干什么的?技術(shù)上,它是一個 管理器(manager) 。 管理器 將在附錄B詳細(xì)描述,在這里你只要知道它處理有關(guān)數(shù)據(jù)表的操作,特別是數(shù)據(jù)查找。
所有的模型都自動擁有一個 objects 管理器;你可以在想要查找數(shù)據(jù)時是使用它。管理器的名稱是可以自己更改的
最后,還有 all() 方法。這是 objects 管理器返回所有記錄的一個方法。 盡管這個對象 看起來象一個列表(list),它實際是一個 QuerySet 對象, 這個對象是數(shù)據(jù)庫中一些記錄的集合。附錄C將詳細(xì)描述QuerySet,現(xiàn)在,我們 就先當(dāng)它是一 個仿真列表對象好了。
QuerySet 代表了你的數(shù)據(jù)庫中的對象的一個集合。它根據(jù)所給參數(shù)可以構(gòu)造若干個 過濾器 來縮小這個集合的規(guī)模。用SQL術(shù)語來講,一個 QuerySet 就相當(dāng)于一個 SELECT 語句,過濾器相當(dāng)于諸如 WHERE 或者 LIMIT 的限定語。對一個模塊來講, Manager 是 QuerySets 的主要來源。它就像一個根本的 QuerySet ,可以對模塊的數(shù)據(jù)庫表中的所有對象進(jìn)行描述。比如,
Blog.objects就是包含著數(shù)據(jù)庫中所有的 Blog 對象的一個根本的 QuerySet 。-
每次都要用 order_by() 顯得有點啰嗦。 大多數(shù)時間你通常只會對某些 字段進(jìn)行排序。在這種情況下,Django讓你可以指定模型的缺省排序方式:
class Meta: ordering = ["name"] 這個 ordering = ["name"] 告訴Django如果沒有顯示提供 order_by() , 就缺省按名稱排序
-
Meta是什么?
- Django使用內(nèi)部類Meta存放用于附加描述該模型的元數(shù)據(jù),查看附錄B,在Meta項下面,獲得更多選項信息
-
你的模型的每個字段應(yīng)該是一個適當(dāng)?shù)?Field 類的實例,Django使用這個字段類的類型去確定如下內(nèi)容:
- 數(shù)據(jù)庫列類型(如 INTEGER 、 VARCHAR )。
- 在Django的admin界面中使用的部件,如果你想要指定的話.(例如:
<input type="text"><select>) - 用于Django的admin界面的基本的合法性驗證。
通用字段選項
- 模型的Metadata選項:
- db_table -- 模型對應(yīng)的數(shù)據(jù)庫表的名字
- ordering -- 對象默認(rèn)的排序方法,獲取對象列表時會用到 ordering = ['-title']
- permissions --創(chuàng)建對象時,需要額外加入權(quán)限表的權(quán)限
- verbose_name -- 對象的友好可讀名稱(單數(shù)形式)
管理器:
- Manager 是提供給Django模型的數(shù)據(jù)庫查詢接口。Django程序的每個模型中至少存在一個 Manager
- 管理器默認(rèn)名稱為 objects, people = models.Manager() 可通過定義修改
URLconf 技巧
- URLconf 中為某個特別的模式指定視圖函數(shù):你可以傳入一個包含模塊名和函數(shù)名的字符串,而不是函數(shù)對象本身
- 應(yīng)該使用帶引號的 'mysite.views.current_datetime' 而不是 mysite.views.current_datetime當(dāng)使用字符串技術(shù)時,你可以采用更簡化的方式:提取出一個公共視圖前綴。在我們的 URLconf 例子中,每一個視圖字符串都是以 'mysite.views' 開始的,造成過多的輸入。我們可以提取出公共前綴然后把它作為第一個參數(shù)傳給 patterns()
urlpatterns = patterns('mysite.views',
(r'^now/$', 'current_datetime'),
(r'^now/plus(\d{1,2})hours/$', 'hours_ahead'),
(r'^now/minus(\d{1,2})hours/$', 'hours_behind'),
(r'^now/in_chicago/$', 'now_in_chicago'),
(r'^now/in_london/$', 'now_in_london'),
)
- urls.py 文件中 patterns()對象可以有很多個,需要疊加處理,如下示例:
urlpatterns = patterns() urlpatterns += patterns() - url正則表達(dá)式中獲取參數(shù)可以使用()
(r'^articles/(\d{4})/$', views.year_archive)
- 也可以使用命名正則表達(dá)式:命名的正則表達(dá)式組的語法是 (?P<name>pattern) ,這里 name 是組的名字,而 pattern 是匹配的某個模式
(r'^articles/(?P<year>\d{4})/$', views.year_archive),
-
理解匹配/分組算法:
- 需要注意的是如果在URLconf中使用命名組,那么命名組和非命名組是不能同時存在于同一個URLconf的模式中的。如果你這樣做,Django不會拋出任何錯誤,但你可能會發(fā)現(xiàn)你的URL并沒有像你預(yù)想的那樣匹配正確。
- 具體地,以下是URLconf解釋器有關(guān)正則表達(dá)式中命名組和非命名組所遵循的算法。
- 如果有任何命名的組,Django會忽略非命名組而直接使用命名組。
- 否則,Django會把所有非命名組以位置參數(shù)的形式傳遞。
- 在以上的兩種情況,Django同時會以關(guān)鍵字參數(shù)的方式傳遞一些額外參數(shù)。更具體的信息可參考下一節(jié)。
偽造捕捉到的URLconf值
你可能會想增加這樣一個URL, /mydata/birthday/ , 這個URL等價于 /mydata/jan/06/ 。這時你可以這樣利用額外URLconf參數(shù)
(r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}),
-
通過使用額外的URLconf參數(shù),給視圖函數(shù)傳遞額外參數(shù)
# urls.py from django.conf.urls.defaults import * from mysite import models, views urlpatterns = patterns('', (r'^events/$', views.object_list, {'model': models.Event}), (r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}), ) # views.py from django.shortcuts import render_to_response def object_list(request, model): obj_list = model.objects.all() template_name = 'mysite/%s_list.html' % model.__name__.lower() return render_to_response(template_name, {'object_list': obj_list}) 我們通過 model 參數(shù)直接傳遞了模型類。額外URLconf參數(shù)的字典是可以傳遞任何類型的對象,而不僅僅只是字符串。
這一行: model.objects.all() 是 鴨子界定 (原文:duck typing,是計算機科學(xué)中一種動態(tài)類型判斷的概念)的一個例子:如果一只鳥走起來像鴨子,叫起來像鴨子,那我們就可以把它當(dāng)作是鴨子了。需要注意的是代碼并不知道 model 對象的類型是什么;它只要求 model 有一個 objects 屬性,而這個屬性有一個 all() 方法。
了解捕捉值和額外參數(shù)之間的優(yōu)先級
(r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
當(dāng)沖突出現(xiàn)的時候,額外URLconf參數(shù)優(yōu)先于捕捉值。也就是說,如果URLconf捕捉到的一個命名組變量和一個額外URLconf參數(shù)包含的變量同名時,額外URLconf參數(shù)的值會被使用。
每個被捕獲的參數(shù)將被作為純Python字符串來發(fā)送,而不管正則表達(dá)式中的格式
短路邏輯
urlpatterns = patterns('',
...
('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
...
)
在這種情況下,象 /auth/user/add/ 的請求將會被 user_add_stage 視圖處理。盡管URL也匹配第二種模式,它會先匹配上面的模式。(這是短路邏輯)
當(dāng)一個請求進(jìn)來時,Django試著將請求的URL作為一個普通Python字符串進(jìn)行URLconf模式匹配(而不是作為一個Unicode字符串
-
包含其他URLconf include()
urlpatterns = patterns('', (r'^weblog/', include('mysite.blog.urls')), (r'^photos/', include('mysite.photos.urls')), (r'^about/$', 'mysite.views.about'), ) 指向 include() 的正則表達(dá)式并 不 包含一個 $ (字符串結(jié)尾匹配符),但是包含了一個斜桿。每當(dāng)Django遇到 include() 時,它將截斷匹配的URL,并把剩余的字符串發(fā)往包含的URLconf作進(jìn)一步處理。
被捕獲的參數(shù)總是傳遞到被包含的URLconf中的每一行,不管那些行對應(yīng)的視圖是否需要這些參數(shù)
額外的選項參數(shù)將總是被傳遞到被包含的URLconf中的每一行,不管那一行對應(yīng)的視圖是否確實作為有效參數(shù)接收這些選項
深入模板引擎
- 自定義過濾器
from django import template
register = template.Library()
@register.filter(name='cut')
def cut(value, arg):
return value.replace(arg, '')
-
自定義模板標(biāo)簽
- 編寫編譯函數(shù)
from django import template def do_current_time(parser, token): try: # split_contents() knows not to split quoted strings. tag_name, format_string = token.split_contents() except ValueError: msg = '%r tag requires a single argument' % token.contents[0] raise template.TemplateSyntaxError(msg) return CurrentTimeNode(format_string[1:-1])- 編寫模板節(jié)點
import datetime class CurrentTimeNode(template.Node): def __init__(self, format_string): self.format_string = format_string def render(self, context): now = datetime.datetime.now() return now.strftime(self.format_string)- 注冊標(biāo)簽
from django import template register = template.Library() register.tag('current_time', do_current_time)- 或者使用裝飾器注冊,方法同過濾器一樣
編寫自定義模板加載器
未完待續(xù).....