国产精品一区二区精品_久久小视频_天堂va在线观看_99久久夜色精品国产亚洲96_日本手机在线视频_av成人免费

當(dāng)前位置:首頁(yè) > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 設(shè)計(jì)軟件教程 > 翻譯www.djangobook.com之第十五章:貢獻(xiàn)的其它子框架

翻譯www.djangobook.com之第十五章:貢獻(xiàn)的其它子框架
2010-01-13 23:43:14  作者:  來源:
Python的眾多力量中的一個(gè)是它的"電池導(dǎo)入"哲學(xué),當(dāng)你安裝了Python,它自帶了一個(gè)巨大的常用模塊"標(biāo)準(zhǔn)庫(kù)",你不需要
下載任何其它東西就可以立即開始使用,Django打算遵循這個(gè)哲學(xué),它包含了它自己的對(duì)常用Web開發(fā)任務(wù)有用的附加標(biāo)準(zhǔn)庫(kù)
本章就講述這些附加物

關(guān)于標(biāo)準(zhǔn)庫(kù)
Django的標(biāo)準(zhǔn)庫(kù)位于django.contrib,其中每個(gè)子包都是一個(gè)單獨(dú)部分的附屬功能,這些包沒有必要互相關(guān)聯(lián),但是有些
django.contrib子包可能需要其它包
在django.contrib里功能類型沒有硬性需求,其中有些包包含模型(這樣就需要在你的數(shù)據(jù)庫(kù)安裝數(shù)據(jù)庫(kù)表),其它的包含單
獨(dú)的中間件或模板標(biāo)簽
django.contrib包的共有特性是:如果你刪除整個(gè)django.contrib包,你仍然可以無誤的使用Django的基本功能,當(dāng)Django
開發(fā)人員往框架添加新功能時(shí),他們使用該規(guī)則來決定新功能應(yīng)該位于django.contrib還是別的地方
django.contrib包含了如下包:
1,admin--自動(dòng)admin站點(diǎn),參考第6章
2,auth--Django的認(rèn)證框架,參考第12章
3,comments--一個(gè)注釋框架,參考第13章
4,contenttypes--一個(gè)深入內(nèi)容類型的框架,其中每個(gè)安裝的Django模型是單獨(dú)的內(nèi)容類型,參考下面的"內(nèi)容類型"
5,csrf--防止跨站點(diǎn)請(qǐng)求偽造(Cross Site Request Forgeries),參考下面的"CSRF預(yù)防"
6,flatpages--在數(shù)據(jù)庫(kù)管理簡(jiǎn)單的"平坦的"HTML,參考下面的"Flatpages"
7,formtools--Django表單的高級(jí)抽象工具,參考下面的"表單工具"
8,humanize--一些Django模板過濾器,對(duì)于給數(shù)據(jù)添加"人類感觀"很有用,參考下面的"使數(shù)據(jù)人性華"
9,markup--一些Django模板過濾器,它們實(shí)現(xiàn)了一些常用的標(biāo)記語言,參考下面的"標(biāo)記過濾器"
10,redirects--一個(gè)管理重定向的框架,參考下面的"重定向"
11,sessions--Django的session框架,參考第12章
12,sitemaps--一個(gè)生成站點(diǎn)圖XML文件的框架,參考下面的"Sitemaps"
13,sites--一個(gè)讓你操作同一數(shù)據(jù)庫(kù)和Django安裝的多個(gè)網(wǎng)站的框架,參考下面的"Sites"
14,syndication--一個(gè)在RSS和Atom生成syndication種子的框架,參考下面的"Syndication種子"
本章的其它部分進(jìn)入每個(gè)django.contrib包的細(xì)節(jié)

Sites
Django的"sites"系統(tǒng)是一個(gè)讓你操作同一數(shù)據(jù)庫(kù)和Django項(xiàng)目的多個(gè)網(wǎng)站的框架,由于這是個(gè)抽象概念,它很難理解,所以
我們以幾個(gè)例子開始

例子1:在多個(gè)站點(diǎn)重用數(shù)據(jù)
我們第1章解釋到,Django驅(qū)動(dòng)的站點(diǎn)LJWorld.com和Lawrence.com被同一新聞組織操作--堪薩斯勞倫斯的Lawrence Journal-
World報(bào)紙,LJWorld.com關(guān)注新聞,而Lawrence.com關(guān)注本地娛樂,但是有時(shí)候編輯想在兩個(gè)站點(diǎn)發(fā)表同一文章
解決此問題的要命的方法是為每個(gè)站點(diǎn)使用不同的數(shù)據(jù)庫(kù),然后讓站點(diǎn)生成者發(fā)表同一個(gè)故事兩次:一次在LJWorld.com一次
在Lawrence.com,但是這使站點(diǎn)生成者很低效,并且它在數(shù)據(jù)庫(kù)里存儲(chǔ)了同一故事的多份拷貝從而造成冗余
更好的解決方案非常簡(jiǎn)單:兩個(gè)站點(diǎn)使用同一文章數(shù)據(jù)庫(kù),并且文章通過多對(duì)多關(guān)系關(guān)聯(lián)到多個(gè)站點(diǎn),Django的sites框架提
供了文章可以被關(guān)聯(lián)的數(shù)據(jù)庫(kù)表,同多個(gè)"sites"關(guān)聯(lián)數(shù)據(jù)是個(gè)鉤子

例子2:在一個(gè)地方存儲(chǔ)你的站點(diǎn)名/域名
LJWorld.com和Lawrence.com都有e-mail提醒功能,這讓讀者訂閱并當(dāng)新聞發(fā)生時(shí)得到告示,這非常基本:讀者在一個(gè)Web表單
訂閱,然后他立即得到一個(gè)e-mail說,"感謝你的訂閱"
實(shí)現(xiàn)該登錄處理代碼兩次是非常低效和冗余的,所以sites在幕后使用了同樣的代碼,但是"感謝你的訂閱"這個(gè)通知需要當(dāng)前
站點(diǎn)的name(如'LJWorld.com')和domain(如'www.ljworld.com')的值
Django的sites框架提供了一個(gè)讓你在你的Django項(xiàng)目里為每個(gè)站點(diǎn)存儲(chǔ)name和domain的地方,這意味著你可以用一個(gè)一般的
方式來重用這些值

使用sites框架
sites框架不像是一個(gè)框架而更像是一些慣例,它整個(gè)東西是基于兩個(gè)簡(jiǎn)單的概念:
1,Site模型,位于djang.contrib.sites,它有domain和name域
2,settings文件里的SITE_ID設(shè)置指定了Site對(duì)象的數(shù)據(jù)庫(kù)ID
怎樣使用這兩個(gè)概念取決于你,但是Django通過簡(jiǎn)單的慣例用一些方式自動(dòng)的使用它們
按下面的步驟安裝sites app:
1,添加'django.contrib.sites'到你的INSTALLED_APPS
2,運(yùn)行命令manage.py syncdb來在你的數(shù)據(jù)庫(kù)安裝django_site表
3,通過Django的admin站點(diǎn)或者Python API來添加一個(gè)或多個(gè)Site對(duì)象,為該Django項(xiàng)目擁有的每個(gè)站點(diǎn)/域名創(chuàng)建Site對(duì)象
4,在你的每個(gè)settings文件中定義SITE_ID,這個(gè)值應(yīng)該為該settings文件驅(qū)動(dòng)的站點(diǎn)的Site對(duì)象的數(shù)據(jù)庫(kù)ID

你可以用sites框架做的事情
在多個(gè)站點(diǎn)間重用數(shù)據(jù)
為了像"例子1"中解釋的那樣在多個(gè)站點(diǎn)重用數(shù)據(jù),只需在你的模型中創(chuàng)建一個(gè)ManyToManyField到Site,例如:
Java代碼 復(fù)制代碼
  1. from django.db import models   
  2. from django.contrib.sites.models import Site   
  3.   
  4. class Article(models.Model):   
  5.     headline = models.CharField(maxlength=200)   
  6.     # ...   
  7.     sites = models.ManyToManyField(Site)  

這是為了在你的數(shù)據(jù)庫(kù)中將文章關(guān)聯(lián)到多個(gè)站點(diǎn)所需的必要基本組織,而且你還可以對(duì)多個(gè)站點(diǎn)重用同樣的Django視圖代碼
繼續(xù)Article例子,這里是article_detail的視圖的樣子:
Java代碼 復(fù)制代碼
  1. from django.conf import settings   
  2.   
  3. def article_detail(request, article_id):   
  4.     try:   
  5.         a = Article.objects.get(id=article_id, sites__id=settings.SITE_ID)   
  6.     except Article.DoesNotExist:   
  7.         raise Http404   
  8.     # ...  

該視圖方法是可重用的,因?yàn)樗鶕?jù)SITE_ID設(shè)置的值來動(dòng)態(tài)檢查文章的站點(diǎn)
例如,LJWorld.com的settings文件的SITE_ID設(shè)置為1而Lawrence.com的settings文件的SITE_ID設(shè)置為2,如果當(dāng)LJWorld.
com的settings文件是活動(dòng)時(shí)調(diào)用該視圖,則它將限制文章查詢?cè)诎琇JWorld.com的sites列表的文章

與單獨(dú)的站點(diǎn)關(guān)聯(lián)內(nèi)容
同樣的,你可以使用ForeignKey和多對(duì)一關(guān)系來關(guān)聯(lián)模型到Site模型
例如,如果文章只允許在一個(gè)單獨(dú)的站點(diǎn),你可以像這樣使用模型:
Java代碼 復(fù)制代碼
  1. from django.db import models   
  2. from django.contrib.sites.models import Site   
  3.   
  4. class Article(models.Model):   
  5.     headline = models.CharField(maxlength=200)   
  6.     # ...   
  7.     site = models.ForeignKey(Site)  

上一部分描述了同樣的好處

從視圖進(jìn)入當(dāng)前站點(diǎn)
在更低的級(jí)別,你可以基于視圖在哪個(gè)site調(diào)用在你的Django視圖使用sites框架來做特殊的事情,例如:
Java代碼 復(fù)制代碼
  1. from django.conf import settings   
  2.   
  3. def my_view(request):   
  4.     if settings.SITE_ID == 3:   
  5.         # Do something.   
  6.     else:   
  7.         # Do something else.  

當(dāng)然,這丑陋的硬編碼了站點(diǎn)IDs,你最好趕緊修正它,一個(gè)達(dá)到同樣目的的稍微干凈的方式是檢查當(dāng)前站點(diǎn)的域名:
Java代碼 復(fù)制代碼
  1. from django.conf import settings   
  2. from django.contrib.sites.models import Site   
  3.   
  4. def my_view(request):   
  5.     current_site = Site.objects.get(id=settings.SITE_ID)   
  6.     if current_site.domain == 'foo.com':   
  7.         # Do something   
  8.     else:   
  9.         # Do something else.  

根據(jù)settings.SITE_ID得到Site對(duì)象的慣例非常常見,所以Site模型的manager(Site.objects)有一個(gè)get_current()方法
這個(gè)例子等同于前面的:
Java代碼 復(fù)制代碼
  1. from django.contrib.sites.models import Site   
  2.   
  3. def my_view(request):   
  4.     current_site = Site.objects.get_current()   
  5.     if current_site.domain == 'foo.com':   
  6.         # Do something   
  7.     else:   
  8.         # Do something else.  

注意在這個(gè)最好的例子中,你不需要import djang.conf.settings

得到當(dāng)前域名來顯示
對(duì)于在"例子2"中解釋的DRY(Don't Repeat Yourself)方式的存儲(chǔ)你的站點(diǎn)名和域名,只需在當(dāng)前Site對(duì)象引用name和domain
例如:
Java代碼 復(fù)制代碼
  1. from django.contrib.sites.models import Site   
  2. from django.core.mail import send_mail   
  3.   
  4. def register_for_newsletter(request):   
  5.     # Check form values, etc., and subscribe the user.   
  6.     # ...   
  7.     current_site = Site.objects.get_current()   
  8.     send_mail('Thanks for subscribing to %s alerts' % current_site.name,   
  9.         'Thanks for your subscription. We appreciate it.\n\n-The %s team.' % current_site.name,   
  10.         'editor@%s' % current_site.domain,   
  11.         [user_email])   
  12.     # ...  

繼續(xù)我們的LJWorld.com和Lawrence.com的例子:在Lawrence.com,這個(gè)e-mail有一個(gè)主題行"Thanks for subscribing to La
wrence.com alers."在LJWorld.com,這個(gè)e-mail主題為"Thanks for subscribing to LJWorld.com alerts."同樣的站點(diǎn)特
有的行為在e-mail的信息主體里完成
注意一個(gè)更靈活(但是更重量級(jí))的完成這個(gè)的方式是使用Django的模板系統(tǒng),假設(shè)Lawrence.com和LJWorld.com有不同的模板
目錄(TEMPLATE_DIRS),你可以像這樣簡(jiǎn)單的委派給模板系統(tǒng):
Java代碼 復(fù)制代碼
  1. from django.core.mail import send_mail   
  2. from django.template import loader, Context   
  3.   
  4. def register_for_newsletter(request):   
  5.     # Check form values, etc., and subscribe the user.   
  6.     # ...   
  7.     subject = loader.get_template('alerts/subject.txt').render(Context({}))   
  8.     message = loader.get_template('alerts/message.txt').render(Context({}))   
  9.     send_mail(subject, message, 'do-not-reply@example.com', [user_email])   
  10.     # ...  

這種情況下,你不需要在LJWorld.com和Lawrence.com模板目錄都創(chuàng)建subject.txt和message.txt模板,這給你更多的靈活性
但是也更復(fù)雜
盡可能多的使用Site對(duì)象來刪除不必要的復(fù)雜性和冗余是個(gè)好主意

為完整URLs得到當(dāng)前域名
Django的get_absolute_url()慣例對(duì)不要域名而得到你的對(duì)象的URL很好,但是某些情況下你可能想顯示完整的URL--用http:
//和域名和任何東西--對(duì)于一個(gè)對(duì)象,為了做這個(gè),你可以使用sites框架,一個(gè)簡(jiǎn)單的例子:
Java代碼 復(fù)制代碼
  1. >>> from django.contrib.sites.models import Site   
  2. >>> obj = MyModel.objects.get(id=3)   
  3. >>> obj.get_absolute_url()   
  4. '/mymodel/objects/3/'  
  5. >>> Site.objects.get_current().domain   
  6. 'example.com'  
  7. >>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())   
  8. 'http://example.com/mymodel/objects/3/'  


CurrentSiteManager
如果Sites在你的程序里擔(dān)任一個(gè)關(guān)鍵的角色,考慮在你的模型里使用有用的CurrentSiteManager,是模型manager(參考第5
章)自動(dòng)過濾它的查詢來包含當(dāng)前Site相關(guān)的對(duì)象
通過顯示的添加CurrentSiteManager到你的模型中來使用它,例如:
Java代碼 復(fù)制代碼
  1. from django.db import models   
  2. from django.contrib.sites.models import Site   
  3. from django.contrib.sites.managers import CurrentSiteManager   
  4.   
  5. class Photo(models.Model):   
  6.     photo = models.FileField(upload_to='/home/photos')   
  7.     photographer_name = models.CharField(maxlength=100)   
  8.     pub_date = models.DateField()   
  9.     site = models.ForeignKey(Site)   
  10.     objects = models.Manager()   
  11.     on_site = CurrentSiteManager()  

對(duì)這個(gè)模型,Photo.objects.all()將返回?cái)?shù)據(jù)庫(kù)中所有的Photo對(duì)象,但是Photo.on_site.all()將根據(jù)SITE_ID設(shè)置只返回
當(dāng)前站點(diǎn)相關(guān)聯(lián)的Photo對(duì)象
換句話說,這兩個(gè)語句是相等的:
Java代碼 復(fù)制代碼
  1. Photo.objects.filter(site=settings.SITE_ID)   
  2. Photo.on_site.all()  

CurrentSiteManager怎么知道Photo的哪個(gè)域是Site?它默認(rèn)查找叫site的域,如果你的模型有一個(gè)ForeignKey或者M(jìn)anyToMan
yField叫site以外的東西,你需要將它作為參數(shù)顯示的傳遞給CurrentSiteManager,下面的域叫publish_on的模型做了示范:
Java代碼 復(fù)制代碼
  1. from django.db import models   
  2. from django.contrib.sites.models import Site   
  3. from django.contrib.sites.managers import CurrentSiteManager   
  4.   
  5. class Photo(models.Model):   
  6.     photo = models.FileField(upload_to='/home/photos')   
  7.     photographer_name = models.CharField(maxlength=100)   
  8.     pub_date = models.DateField()   
  9.     publish_on = models.ForeignKey(Site)   
  10.     objects = models.Manager()   
  11.     on_site = CurrentSiteManager('publish_on')  

如果你嘗試使用CurrentSiteManager并傳遞一個(gè)不存在的域的名字Django將觸發(fā)ValueError
最后,注意即使你使用CurrentSiteManager,你可能想在你的模型保持一個(gè)普通(非站點(diǎn)專有)的Manager,在第5章解釋了,
如果你手動(dòng)定義一個(gè)manager,則Django不會(huì)為你自動(dòng)創(chuàng)建objects = models.Manager(),同時(shí)注意Django的某些部分--即
Django的admin站點(diǎn)和generic views--使用模型中首先定義的manager,所以如果你想讓你的admin站點(diǎn)訪問所有的對(duì)象(而
不只是站點(diǎn)專有的對(duì)象),在定義CurrentSiteManager之前把objects = models.Manager()放置到你的模型中

Django怎樣使用sites框架
盡管使用sites框架不是必需的,但這是強(qiáng)力推薦的,因?yàn)镈jango在一些地方使用它,即使你的Django安裝只是單站點(diǎn)驅(qū)動(dòng)
你應(yīng)該花費(fèi)兩秒鐘來使用你的domain和name來創(chuàng)建site對(duì)象,并在你的SITE_ID設(shè)置里指出它的ID
這里是Django怎樣使用sites框架:
1,在重定向框架(參考下面的"重定向")中,每個(gè)重定向?qū)ο笈c特殊的站點(diǎn)相關(guān)聯(lián),當(dāng)Django搜索一個(gè)重定向時(shí),它考慮當(dāng)
前的SITE_ID
2,在注釋框架(參考第13章)中,每個(gè)注釋與特殊的站點(diǎn)相關(guān)聯(lián),當(dāng)發(fā)表一個(gè)注釋時(shí),它的site設(shè)置為SITE_ID,當(dāng)注釋通過
合適的模板標(biāo)簽列出時(shí),只顯示當(dāng)前站點(diǎn)的注釋
3,在flatpages框架中(參考下面的"Flatpages"),每個(gè)flatpage與一個(gè)特殊的站點(diǎn)相關(guān)聯(lián),當(dāng)flatpage創(chuàng)建時(shí),你指定它的
site,并且flatpage中間件在得到flatpages時(shí)檢查當(dāng)前SITE_ID來顯示
4,在syndication框架中(參考下面的"Syndication種子"),title和description的模板自動(dòng)訪問{{{ site }}}變量,它是
表示當(dāng)前站點(diǎn)的Site對(duì)象,而且如果你不指定完整的域名,提供條目URLs的鉤子將使用當(dāng)前Site對(duì)象的domain

Flatpages
你經(jīng)常有一個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的Web程序要運(yùn)行,但是你將需要添加一些"一次性的"靜態(tài)頁(yè)面,例如"About"頁(yè)面或者"私有政策"
頁(yè)面,可以使用標(biāo)準(zhǔn)Web服務(wù)器如Apache來將其作為平坦的HTML文件服務(wù),但是這在你的程序中導(dǎo)致了額外級(jí)別的復(fù)雜度,因
為你需要擔(dān)心配置Apache,你需要建立讓你的團(tuán)隊(duì)編輯這些文件的訪問方式,并且你不能使用Django的模板系統(tǒng)來給這些頁(yè)
面添加風(fēng)格
這個(gè)問題的解決方案是Django的"flatpages"app,它位于django.contrib.flatpages包,這個(gè)app讓你通過Django的admin站
點(diǎn)管理這些"一次性"頁(yè)面,并讓你使用Django的模板系統(tǒng)為它們指定模板,它在幕后使用Django模型,這意味著你在數(shù)據(jù)庫(kù)
存儲(chǔ)這些頁(yè)面,就像你的其它數(shù)據(jù)一樣,并且你可以使用Django的標(biāo)準(zhǔn)數(shù)據(jù)庫(kù)API訪問flatpages
Flatpages通過它們的URL和site作為鍵來維護(hù),當(dāng)你創(chuàng)建一個(gè)flatpage,你指定它關(guān)聯(lián)的URL以及它所在的站點(diǎn)(參考上面的
"Sites"部分得到更多關(guān)于sites)

使用Flatpages
按下面步驟安裝flatpages app:
1,把'django.contrib.flatpages'添加到你的INSTALLED_APPS
2,把'django.contrib.flatpages.middleware.FlatpageFallbckMiddleware'添加到你的MIDDLEWARE_CLASSES設(shè)置
3,運(yùn)行命令manage.py syncdb來安裝兩個(gè)必需的表到你的數(shù)據(jù)庫(kù)

它怎樣工作
flatpages app在你的數(shù)據(jù)庫(kù)創(chuàng)建了兩個(gè)表:django_flatpage和django_flatpage_sites,django_flatpage是一個(gè)簡(jiǎn)單映射
一個(gè)URL到一個(gè)title和一些文本內(nèi)容的查詢表,django_flatpage_sites是將一個(gè)flatpage同一個(gè)或多個(gè)站點(diǎn)關(guān)聯(lián)的多對(duì)多表
該app帶有一個(gè)單獨(dú)的FlatPage模型,定義在django/contrib/flatpages/models.py,它看起來像這樣:
Java代碼 復(fù)制代碼
  1. from django.db import models   
  2. from django.contrib.sites.models import Site   
  3.   
  4. class FlatPage(models.Model):   
  5.     url = models.CharField(maxlength=100)   
  6.     title = models.CharField(maxlength=200)   
  7.     content = models.TextField()   
  8.     enable_comments = models.BooleanField()   
  9.     template_name = models.CharField(maxlength=70, blank=True)   
  10.     registration_required = models.BooleanField()   
  11.     sites = models.ManyToManyField(Site)  

讓我們一次看看所有這些域:
1,url--flatpage位于的URL,不包含域名但包含前置斜線,例如:'/about/contact/'
2,title--flatpage的title,框架不對(duì)它做任何特殊的事情,在模板中顯示它是你的責(zé)任
3,content--flatpage的內(nèi)容,即頁(yè)面的HTML,框架不對(duì)它做任何特殊的事情,在模板中顯示它是你的責(zé)任
4,enable_comments--是否在flatpage允許注釋,框架不對(duì)它做任何特殊的事情,你可以在你的模板中檢查該值并需要的話
顯示一個(gè)注釋表單
5,template_name--用來渲染該flatpage的的模板名,它是可選的,如果它沒有給出,框架將使用模板flatpages/default.
html
6,registration_required--注冊(cè)對(duì)于查看該flatpage是否必需,它與第12章解釋的Django的認(rèn)證/用戶框架集成
7,sites--該flatpage位于的站點(diǎn),它與上面的"Sites"部分解釋的Django的sites框架繼承
你可以通過Django的admin界面或者Django數(shù)據(jù)庫(kù)API創(chuàng)建flatpages,參考下面的"怎樣添加,更改和刪除flatpages"
一旦你創(chuàng)建了flatpages,F(xiàn)latpageFallbackMiddleware做所有的工作,每次Django程序觸發(fā)404錯(cuò)誤時(shí),該中間件對(duì)請(qǐng)求的
URL檢查flatpages數(shù)據(jù)庫(kù)作為最后的手段,特別的,它使用給定的URL和表示SITE_ID設(shè)置的站點(diǎn)ID來檢查flatpage
如果它找到一個(gè)匹配,它就載入flatpage的模板或者如果flatpage沒有指定自定義模板時(shí)使用flatpages/default.html,它
傳遞給模板一個(gè)單獨(dú)的context變量flatpage,它是flatpage對(duì)象,然后使用RequestContext渲染模板
如果它沒找到匹配,請(qǐng)求繼續(xù)照常處理
注意該中間件只為404激活--而不為500或其它狀態(tài)碼的應(yīng)答,同時(shí)注意MIDDLEWARE_CLASSES的順序有關(guān)系,一般來說,你可
以將FlatpageFallbackMiddleware放在列表的末尾,因?yàn)樗亲詈蟮氖侄?

怎樣添加,更改和刪除flatpages
通過admin界面
如果你激活了自動(dòng)的Django的admin界面,你應(yīng)該在admin首頁(yè)看到一個(gè)"Flatpages"部分,在系統(tǒng)中像編輯其它對(duì)象一樣編輯
flatpages
通過Python API
上面描述了,flatpages通過位于django/contrib/flatpages/models.py的標(biāo)準(zhǔn)Django模型來表示,這樣,你可以通過標(biāo)準(zhǔn)
Django數(shù)據(jù)庫(kù)API訪問flatpage對(duì)象,例如:
Java代碼 復(fù)制代碼
  1. >>> from django.contrib.flatpages.models import FlatPage   
  2. >>> from django.contrib.sites.models import Site   
  3. >>> fp = FlatPage(   
  4. ...     url='/about/',   
  5. ...     title='About',   
  6. ...     content='<p>About this site...</p>',   
  7. ...     enable_comments=False,   
  8. ...     template_name='',   
  9. ...     registration_required=False,   
  10. ... )   
  11. >>> fp.save()   
  12. >>> fp.sites.add(Site.objects.get(id=1))   
  13. >>> FlatPage.objects.get(url='/about/')   
  14. <FlatPage: /about/ -- About>  


Flatpage模板
flatpages默認(rèn)通過模板flatpages/default.html渲染,但是你可以對(duì)應(yīng)該特殊的flatpage覆蓋它
創(chuàng)建flatpages/default.html模板是你的責(zé)任,在你的模板目錄創(chuàng)建flatpages目錄并包含一個(gè)default.html文件
Faltpage模板傳遞了一個(gè)單獨(dú)的context變量flatpage,它是flatpage對(duì)象
這里是flatpages/default.html模板的例子:
Java代碼 復(fù)制代碼
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"  
  2.     "http://www.w3.org/TR/REC-html40/loose.dtd">   
  3. <html>   
  4. <head>   
  5. <title>{{ flatpage.title }}</title>   
  6. </head>   
  7. <body>   
  8. {{ flatpage.content }}   
  9. </body>   
  10. </html>  


重定向
Django的重定向框架讓你通過在數(shù)據(jù)庫(kù)里存儲(chǔ)它們來輕松管理重定向并把它們當(dāng)作其它Django模型對(duì)象,例如你可以使用重
定向框架來告訴Django,"重定向任何對(duì)/music/的請(qǐng)求到/sections/arts/music/"

使用重定向框架
按下面步驟安裝重定向app:
1,把'django.contrib.redirects'安裝到你的INSTALLED_APPS
2,把'django.contrib.redirects.middleware.RedirectFallbackMiddleware'添加到你點(diǎn)MIDDLEWARE_CLASSES設(shè)置
3,運(yùn)行命令manage.py syncdb來安裝單獨(dú)的必需表到你的數(shù)據(jù)庫(kù)

它怎樣工作
manage.py syncdb在你的數(shù)據(jù)庫(kù)安裝了一個(gè)django_redirect表,它是有site_id,old_path和new_path域的簡(jiǎn)單查詢表
你可以通過Django的admin界面或者Django數(shù)據(jù)庫(kù)API創(chuàng)建重定向,參考下面的"怎樣添加,更改和刪除重定向"
一旦你創(chuàng)建了重定向,RedirectFallbackMiddleware做所有的工作,每次Django程序觸發(fā)了404錯(cuò)誤,中間件都將檢查重定向
表作為最后的手段,特別的,它使用給定的old_path和表示SITE_ID設(shè)置的站點(diǎn)ID來檢查重定向(參考上面的"Sites"來得到更
多關(guān)于SITE_ID和sites框架),然后,它遵循下面的步驟:
1,如果它找到匹配,并且new_path不為空,則它將重定向到new_path
2,如果它找到匹配,并且new_path為空,它發(fā)送一個(gè)410("不存在")HTTP頭部和空(無內(nèi)容)應(yīng)答
3,如果它找不到匹配,請(qǐng)求繼續(xù)照常處理
中間件只為404激活--不為400或者任何其它狀態(tài)碼的應(yīng)答
注意MIDDLEWARE_CLASSES的順序有關(guān)系,一般來說,你可以將RedirectFallbackMiddleware放置在列表末尾,因?yàn)樗亲詈?
的手段

怎樣添加,更改和刪除重定向
通過admin界面
如果你激活了自動(dòng)的Django的admin界面,你應(yīng)該在admin首頁(yè)看到一個(gè)"重定向"部分,在系統(tǒng)中像編輯任何其它對(duì)象一樣編
輯重定向
通過Python API
重定向通過位于django/contrib/redirects/models.py的標(biāo)準(zhǔn)Django模型表示,這樣你可以通過Django數(shù)據(jù)庫(kù)API訪問重定向
對(duì)象,例如:
Java代碼 復(fù)制代碼
  1. >>> from django.contrib.redirects.models import Redirect   
  2. >>> from django.contrib.sites.models import Site   
  3. >>> red = Redirect(   
  4. ...     site=Site.objects.get(id=1),   
  5. ...     old_path='/music/',   
  6. ...     new_path='/sections/arts/music/',   
  7. ... )   
  8. >>> red.save()   
  9. >>> Redirect.objects.get(old_path='/music/')   
  10. <Redirect: /music/ ---> /sections/arts/music/>  


CSRF防護(hù)
django.contrib.csrf包提供了容易使用的跨站點(diǎn)請(qǐng)求偽造Cross-Site Request Forgeries(CSRF)防護(hù)

CSRF解釋
CSRF,也稱為"session駕馭",它是一個(gè)Web站點(diǎn)安全開拓,當(dāng)一個(gè)惡毒的網(wǎng)站欺騙用戶未知的從一個(gè)他們已經(jīng)認(rèn)證站點(diǎn)載入
一個(gè)URL--這樣就可以使用他們的認(rèn)證狀態(tài),這起初可能有點(diǎn)難以理解,所以這里我們包含了兩個(gè)例子:
一個(gè)簡(jiǎn)單的例子
比如說你已經(jīng)在example.com登錄了一個(gè)webmail帳號(hào),這個(gè)webmail站點(diǎn)有一個(gè)"注銷"按鈕指向URL為example.com/logout--
即你為了注銷所需要做的唯一的動(dòng)作是訪問example.com/logout頁(yè)面
惡毒的站點(diǎn)可以通過把URL example.com/logout包含在他自己(惡毒的)頁(yè)面的一個(gè)隱藏的iframe來強(qiáng)迫你訪問該URL,這樣
如果你在example.com登錄了webmail帳號(hào)并訪問有example.com/logout的iframe的惡毒頁(yè)面,訪問該惡毒頁(yè)面的結(jié)果是將
你從example.com注銷
顯然,不按你的意愿從一個(gè)webmail站點(diǎn)注銷不是令人恐怖的安全漏洞,但是同類型的開拓可以發(fā)生在任何"信任"用戶的站點(diǎn)
--例如銀行站點(diǎn)或電子商務(wù)站點(diǎn)
一個(gè)更復(fù)雜的例子
在上個(gè)例子中,example.com部分有故障,因?yàn)樗试S通過HTTP GET方法做狀態(tài)更改(即注銷你自己),對(duì)任何請(qǐng)求需要HTTP
POST來在服務(wù)器更改狀態(tài)是一個(gè)良好實(shí)踐,但是即使Web站點(diǎn)需要POST來做狀態(tài)改變對(duì)于CSRF也很易受到攻擊
比方說example.com升級(jí)了它的"注銷"功能為一個(gè)form按鈕來通過POST到URL example.com/logout來請(qǐng)求,而且,注銷form
包含下面隱藏域:
Java代碼 復(fù)制代碼
  1. <input type="hidden" name="confirm" value="true" />  

這保證了簡(jiǎn)單的POST到URL example.com/logout將不執(zhí)行注銷,為了讓用戶注銷,用戶必須通過POST并發(fā)送confirm POST變
量且值為'true'
但是不管額外的安全,這種方式仍然可以被CSRF開拓,惡毒的頁(yè)面只需做一點(diǎn)更多的工作,取代在iframe載入example.com/
logout頁(yè)面,它可以通過使用JavaScript和POST來調(diào)用該URL,并傳遞confirm=true變量
防止
這樣的話,怎樣防止你的站點(diǎn)被開拓呢?
第一步是確認(rèn)所有的GET請(qǐng)求沒有副作用,這樣,如果惡毒的站點(diǎn)包含了一個(gè)你的頁(yè)面作為iframe,它將沒有壞作用
第二步是給每個(gè)POST表單一個(gè)隱藏域,值為隱秘的并從用戶的session ID生成,這樣,當(dāng)在服務(wù)器端處理時(shí)檢查隱秘域,如
果它不合法則觸發(fā)一個(gè)異常
這就是Django的CSRF預(yù)防層做的事情

使用CSRF中間件
djang.csrf包只包含一個(gè)模塊:middleware.py,該模塊包含了Django的中間件類CsrfMiddleware,它實(shí)現(xiàn)了CSRF預(yù)防
為了使用它,把'django.contrib.csrf.middleware.CsrfMiddleware'添加到你的settings文件的MIDDLEWARE_CLASSes設(shè)置中
這個(gè)中間件需要在SessionMiddleware之后處理應(yīng)答,所以CsrfMiddleware必須放在列表的SessionMiddleware之前,它也必
須在應(yīng)答被壓縮或切碎之前處理,所以CsrfMiddleware必須放在GZipMiddleware之后
一旦你將它添加到你的MIDDLEWARE_CLASSES設(shè)置中,你就完成了,這是你需要做的所有的事情

它怎樣工作
如果你感興趣,這里是關(guān)于CsrfMiddleware怎樣工作,它做這兩件事情:
1,它通過使用csrfmiddlewaretoken名和session ID加上密碼的hash值來添加一個(gè)隱藏域到所有的POST表單來修改外出的請(qǐng)
求,如果沒有session ID設(shè)置則中間件不修改應(yīng)答,所以執(zhí)行處罰對(duì)于不使用sessions的請(qǐng)求可以忽略
2,對(duì)于所有進(jìn)來的有session cookie設(shè)置的POST請(qǐng)求,它檢查csrfmiddlewaretoken存在并正確,如果不是這樣,用戶將得
到一個(gè)403HTTP錯(cuò)誤,403錯(cuò)誤頁(yè)面的內(nèi)容是"發(fā)現(xiàn)跨站點(diǎn)請(qǐng)求偽造,請(qǐng)求中止"的信息
這確保了只有你的網(wǎng)站的原始表單可以用來POST回?cái)?shù)據(jù)
該中間件故意只針對(duì)HTTP POST請(qǐng)求(以及相應(yīng)的POST表單),我們上面解釋了,GET請(qǐng)求應(yīng)該從來沒有副作用,確保這點(diǎn)是你
自己的責(zé)任
不通過session cookie完成的POST請(qǐng)求不被預(yù)防,但是它們也不需要預(yù)防,因?yàn)閻憾镜木W(wǎng)站不會(huì)偽造這種類型的請(qǐng)求
為了防止更改非文本請(qǐng)求,中間件在修改它之前檢查應(yīng)答的Content-Type頭部,只有格式為text/html或者application/xml
+xhtml的頁(yè)面被修改

限制
CsrfMiddleware需要Django的session框架來工作(參考第12章),如果你正在使用一個(gè)自定義的手動(dòng)慣例session cookie的
session或者認(rèn)證框架,該中間件將不能幫助你
如果你的app用一些不尋常的方式創(chuàng)建HTML頁(yè)面和表單--例如,如果它用JavaScript的document.write語句傳遞HTML碎片--你
可能迂回添加隱藏域到表單的過濾器,這種情況下,表單提交將一直出錯(cuò)(這會(huì)發(fā)生因?yàn)镃srfMiddleware使用正則表達(dá)式來在
頁(yè)面發(fā)送到客戶端之前添加csrfmiddlewaretoken域到你的HTML,而正則表達(dá)式有時(shí)候不能處理古怪的HTML),如果你懷疑這
可能發(fā)生,只需在你的瀏覽器查看源代碼來看看csrfmiddlewaretoken是否插入到你的表單
訪問http://en.wikipedia.org/wiki/Csrf來得到更多關(guān)于CSRF的信息和例子

內(nèi)容類型
This section hasn't been written yet.

表單工具
This section hasn't been written yet.

使數(shù)據(jù)人性化
This section hasn't been written yet.

標(biāo)記過濾器
This section hasn't been written yet.

Syndication種子
This section hasn't been written yet.
安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
国产精品一区二区精品_久久小视频_天堂va在线观看_99久久夜色精品国产亚洲96_日本手机在线视频_av成人免费
<button id="0mgmq"><pre id="0mgmq"></pre></button>
  • <tr id="0mgmq"></tr>
  • <abbr id="0mgmq"><source id="0mgmq"></source></abbr> <button id="0mgmq"></button>
  • 欧美二区在线看| 欧美理论一区二区| 欧美日本久久| 高清视频一区二区三区| 黄色工厂这里只有精品| 久久国产精品久久| 久久天堂精品| 国产日韩视频| 欧美色综合网| 亚洲乱码国产乱码精品天美传媒| 91传媒在线免费观看| 亚洲日本无吗高清不卡| 一本色道久久综合亚洲精品婷婷| 国产一区二区三区四区hd| 国产精品日韩精品欧美精品| 国产主播精品| 欧美精品亚洲| 亚洲一区二区三区精品视频| 欧美不卡福利| 精品欧美日韩在线| 国产欧美日本在线| 久久国产精品99国产| 亚洲欧洲久久| 国产精品久久7| 欧美日韩国内| 中文精品视频一区二区在线观看| 欧美日韩一区二区三区免费| 精品免费一区二区三区蜜桃| 国产高清不卡av| 福利精品视频| 国产伦理一区二区三区| 99视频国产精品免费观看| **亚洲第一综合导航网站 | 国产一区二区三区无遮挡| 麻豆久久久9性大片| 国产女优一区| 亚洲综合电影一区二区三区| 亚洲综合社区| 114国产精品久久免费观看| 91精品天堂| 国产精品日韩高清| 六月婷婷久久| 日韩色妇久久av| 亚洲第一导航| 欧美日韩午夜| 一本一道久久综合狠狠老精东影业 | 亚洲欧洲三级| 欧美激情五月| 亚洲精品视频啊美女在线直播| 亚洲精品视频啊美女在线直播| 亚洲国产精品第一区二区| 日韩午夜视频在线观看| 亚洲一区三区电影在线观看| 99国精产品一二二线| 国产尤物99| 亚洲精品自在在线观看| 欧美 日韩 国产一区二区在线视频| 欧美大片一区| 国产三区二区一区久久| 91久久精品国产91久久性色tv| 精品国产一区二区三区日日嗨 | 亚洲视频大全| 国产精品视频免费一区| 日韩精品久久一区二区三区| 中文字幕中文字幕在线中心一区| 国内自拍视频一区二区三区| 99在线精品视频在线观看 | 欧美成人精品| 99热这里只有精品8| 大波视频国产精品久久| 亚洲精品一区国产精品| 91久久中文| 国产美女精品久久久| 亚洲高清乱码| 国产三级精品在线不卡| 精品视频导航| 国产一区二区三区四区hd| 久热精品在线| 亚洲春色在线视频| 亚洲一区二区三区欧美| 欧美激情论坛| 精品动漫3d一区二区三区免费| 久热re这里精品视频在线6| 免费看污久久久| 亚洲欧洲精品一区二区| 国产一区喷水| 亚洲第一伊人| 国产一区二区在线网站| 牛牛国产精品| 国产高清一区视频| 欧美午夜视频在线| yellow视频在线观看一区二区| 亚洲视频在线观看日本a| 久久精品女人的天堂av| 综合视频在线观看| 国产欧美一区二区视频 | 成人久久18免费网站漫画| 一区二区精品在线观看| 欧美资源在线| 中文字幕一区二区三区四区五区| 欧美一区=区| 在线观看成人av电影| 国产精品二区在线| 激情综合自拍| 日韩一区二区三区高清| 久久亚洲图片| 亚洲午夜极品| 日本一区二区不卡高清更新| 毛片一区二区| 激情五月***国产精品| 欧洲精品久久| 国产精品视频500部| 亚洲精品国产精品国自产观看| 日本不卡免费新一二三区| 97久久夜色精品国产九色 | 国产传媒一区二区三区| 亚洲精品一区二区三区av| 午夜久久资源| 九九九久久久| 99精彩视频在线观看免费| 亚洲精品一品区二品区三品区| 亚洲精品免费在线看| 国产精品欧美久久| 亚洲欧美日韩视频二区 | 日本中文不卡| 国产综合18久久久久久| 91免费版黄色| 亚洲一区激情| 99热这里只有精品8| 欧美国产综合| 亚洲精蜜桃久在线| 欧美一区二区三区在线免费观看 | 亚洲三级免费| 狠狠色综合网| 欧美一区影院| 日韩视频在线观看国产| 激情视频在线观看一区二区三区| 亚洲欧美日韩视频二区 | 欧美理论在线| 午夜精彩国产免费不卡不顿大片| 日韩av在线电影观看| 麻豆av福利av久久av| 久久精品国产第一区二区三区最新章节 | 视频在线一区二区三区| 免费成人深夜夜行视频| 久久国产主播精品| 久久99精品久久久久久水蜜桃| 国产精品香蕉视屏| 国产99在线播放| y111111国产精品久久婷婷| 99超碰麻豆| 国产一区二区三区av在线| 成人精品一二区| 国产乱码精品一区二区三区日韩精品| 久久久噜噜噜| 久久裸体视频| 成人欧美一区二区三区黑人免费| 另类av一区二区| 成人三级在线| 麻豆一区区三区四区产品精品蜜桃| 国产精品制服诱惑| 品久久久久久久久久96高清| 日本一区二区不卡高清更新| 亚洲欧美日韩国产yyy| 欧美在线免费| 亚洲国产精品综合| 午夜一级在线看亚洲| 国产精品sss| 欧美aaaaa喷水| 欧美一区二区三区在线免费观看 | 久久资源亚洲| 亚洲欧洲一二三| 尹人成人综合网| 久久久久久9| 国产精品视频免费一区二区三区| 另类视频在线观看+1080p| 一区二区精品免费视频| 亚洲国产精品一区二区第一页 | 伊人久久大香线蕉成人综合网| 国产综合欧美| 久久久久综合一区二区三区| 国产精品制服诱惑| 夜夜爽99久久国产综合精品女不卡 | 六月婷婷久久| 久久综合九色综合网站| 女女同性女同一区二区三区91| 亚洲第一伊人| 国产精品美女诱惑| 一区国产精品| 午夜一区二区三区不卡视频| 国产精品一区二区三区在线| 亚洲精品免费在线看| 一区二区三区四区五区视频| 91在线播放视频| 亚洲午夜在线观看| 免费看亚洲片| 色一情一乱一伦一区二区三区丨| 狠狠爱www人成狠狠爱综合网| 久久亚洲综合网| 伊人久久婷婷色综合98网|