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