web框架---Django框架

Django基本命令css

 

1、下載Djangohtml

 

pip3 install djangopython

2、建立一個django projectjquery

django-admin.py startproject mysitenginx

當前目錄下會生成mysite的工程,目錄結構以下:程序員

manage.py ----- Django項目裏面的工具,經過它能夠調用django shell和數據庫等。web

settings.py ---- 包含了項目的默認設置,包括數據庫信息,調試標誌以及其餘一些工做的變量。正則表達式

urls.py ----- 負責把URL模式映射到應用程序。shell

3、在mysite目錄下建立應用數據庫

python manage.py startapp blog

4、啓動django項目

python manage.py runserver 8080

這樣django就啓動起來了,訪問:http://127.0.0.1:8080/

5、同步更改數據庫表或字段

'''

    python manage.py syncdb

    

    注意:Django 1.7.1 及以上的版本須要用如下命令

   python manage.py makemigrations

   python manage.py migrate  

'''

 

這種方法能夠建立表,當你在models.py中新增了類時,運行它就能夠自動在數據庫中建立表了,不用手動建立。

 

6、清空數據庫

python manage.py flush

此命令會詢問是 yes 仍是 no, 選擇 yes 會把數據所有清空掉,只留下空表。

 

7、建立超級管理員

'''

   python manage.py createsuperuser

    #按照提示輸入用戶名和對應的密碼就行了郵箱能夠留空,用戶名和密碼必填

    #修改 用戶密碼能夠用:

   python manage.py changepassword username  

'''

8Django 項目環境終端

python manage.py shell

這個命令和 直接運行 python 進入 shell 的區別是:你能夠在這個 shell 裏面調用當前項目的 models.py 中的 API,對於操做數據的測試很是方便。

 

9Django 項目環境終端

ython manage.py dbshell

Django 會自動進入在settings.py中設置的數據庫,若是是 MySQL postgreSQL,會要求輸入數據庫用戶密碼。

在這個終端能夠執行數據庫的SQL語句。

 

10、更多命令

python manage.py          查看全部的命令,忘記子名稱的時候特別有用。

 

11 靜態文件配置

概述:

     靜態文件交由Web服務器處理,Django自己不處理靜態文件。簡單的處理邏輯以下(nginx爲例)

 

       URI請求-----> 按照Web服務器裏面的配置規則先處理,以nginx爲例,主要求配置在nginx.conf裏的location

                         |---------->若是是靜態文件,則由nginx直接處理

                         |---------->若是不是則交由Django處理,Django根據urls.py裏面的規則進行匹配

 

    以上是部署到Web服務器後的處理方式,爲了便於開發,Django提供了在開發環境的對靜態文件的處理機制,方法是這樣:

static配置:

STATIC主要指的是如css,js,p_w_picpaths這樣文件:

STATIC_URL = '/static/'      # 別名

STATICFILES_DIRS = (

           os.path.join(BASE_DIR,"static"),  #實際名 ,即實際文件夾的名字

       )

'''

注意點1:

 django對引用名和實際名進行映射,引用時,只能按照引用名來,不能按實際名去找

       <script src="/statics/jquery-3.1.1.js"></script>

       ------error-----不能直接用,必須用STATIC_URL= '/static/':

       <script src="/static/jquery-3.1.1.js"></script>

注意點2:

 STATICFILES_DIRS = (

   ("app01",os.path.join(BASE_DIR, "app01/statics")),

       )

 <scriptsrc="/static/app01/jquery.js"></script>

'''

 

have a try

http://127.0.0.1:8000/static/jquery.js

 

media配置:

# in settings:

MEDIA_URL="/media/"

MEDIA_ROOT=os.path.join(BASE_DIR,"app01","media","upload")

# in urls:

from django.views.static import serve

url(r'^media/(?P<path>.*)$', serve,{'document_root': settings.MEDIA_ROOT}),

 

have a try:

http://127.0.0.1:8000/media/1.png

 

'''

       靜態文件的處理又包括STATICMEDIA兩類,這每每容易混淆,在Django裏面是這樣定義的:       

       MEDIA:指用戶上傳的文件,好比在Model裏面的FileFIeldImageField上傳的文件。若是你定義       

       MEDIA_ROOT=c:\temp\media,那麼File=models.FileField(upload_to="abc/")#,上傳的文件就會被保存到c:\temp\media\abc

 

eg

           class blog(models.Model):

                  Title=models.charField(max_length=64)

                   Photo=models.ImageField(upload_to="photo")

         上傳的圖片就上傳到c:\temp\media\photo,而在模板中要顯示該文件,則在這樣寫

         settings裏面設置的MEDIA_ROOT必須是本地路徑的絕對路徑,通常是這樣寫:

                 BASE_DIR=os.path.abspath(os.path.dirname(__file__))

                 MEDIA_ROOT=os.path.join(BASE_DIR,'media/').replace('\\','/')

 

       MEDIA_URL是指從瀏覽器訪問時的地址前綴,舉個例子:

           MEDIA_ROOT=c:\temp\media\photo

           MEDIA_URL="/data/"

       在開發階段,media的處理由django處理:

 

          訪問http://localhost/data/abc/a.png就是訪問c:\temp\media\photo\abc\a.png

 

          在模板裏面這樣寫<imgsrc="/media/abc/a.png">

 

          在部署階段最大的不一樣在於你必須讓web服務器來處理media文件,所以你必須在web服務器中配置,

          以便能讓web服務器能訪問media文件

          nginx爲例,能夠在nginx.conf裏面這樣:

 

                 location ~/media/{

                      root/temp/

                       break;

                    }

 

          具體能夠參考如何在nginx部署django的資料。

 

視圖層之路由配置系統(views)

 

URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL與要爲該URL調用的視圖函數之間的映射表;你就是以這種方式告訴Django,對於這個URL調用這段代碼,對於那個URL調用那段代碼。

 

   '''

    urlpatterns = [

        url(正則表達式, views視圖函數,參數,別名),

]

參數說明:

    一個正則表達式字符串

    一個可調用對象,一般爲一個視圖函數或一個指定視圖函數路徑的字符串

    可選的要傳遞給視圖函數的默認參數(字典形式)

    一個可選的name參數

   '''

 

2.1 URLconf的正則字符串參數

2.1.1 簡單配置

from django.conf.urls import url

from . import views

urlpatterns = [

   url(r'^articles/2003/$', views.special_case_2003),

   url(r'^articles/([0-9]{4})/$', views.year_archive),

   url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),

   url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]

 

 

'''

   NOTE:

    1一旦匹配成功則再也不繼續

    2若要從URL 中捕獲一個值,只須要在它周圍放置一對圓括號。

    3不須要添加一個前導的反斜槓,由於每一個URL 都有。例如,應該是^articles 而不是 ^/articles

    4每一個正則表達式前面的'r' 是可選的可是建議加上。

 

一些請求的例子:

   /articles/2005/3/ 不匹配任何URL 模式,由於列表中的第三個模式要求月份應該是兩個數字。

   /articles/2003/ 將匹配列表中的第一個模式不是第二個,由於模式按順序匹配,第一個會首先測試是否匹配。

   /articles/2005/03/ 請求將匹配列表中的第三個模式。Django 將調用函數

                      views.month_archive(request, '2005', '03')

   '''

#設置項是否開啓URL訪問地址後面不爲/跳轉至帶有/的路徑

APPEND_SLASH=True

 

2.1.2 有名分組(named group)

上面的示例使用簡單的、沒有命名的正則表達式組(經過圓括號)來捕獲URL 中的值並以位置 參數傳遞給視圖。在更高級的用法中,可使用命名的正則表達式組來捕獲URL 中的值並以關鍵字 參數傳遞給視圖。

Python 正則表達式中,命名正則表達式組的語法是(?P<name>pattern),其中name 是組的名稱,pattern 是要匹配的模式。

下面是以上URLconf 使用命名組的重寫:

from django.conf.urls import url

from . import views

 

urlpatterns = [

   url(r'^articles/2003/$', views.special_case_2003),

   url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

   url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.month_archive),

   url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$',views.article_detail),

]

 

這個實現與前面的示例徹底相同,只有一個細微的差異:捕獲的值做爲關鍵字參數而不是位置參數傳遞給視圖函數。例如:

 

   /articles/2005/03/   

    請求將調用views.month_archive(request, year='2005',month='03')函數

   /articles/2003/03/03/

    請求將調用函數views.article_detail(request,year='2003', month='03', day='03')

在實際應用中,這意味你的URLconf會更加明晰且不容易產生參數順序問題的錯誤 —— 你能夠在你的視圖函數定義中從新安排參數的順序。固然,這些好處是以簡潔爲代價;有些開發人員認爲命名組語法醜陋而繁瑣。

 

2.1.3 URLconf 在什麼上查找

URLconf 在請求的URL 上查找,將它當作一個普通的Python字符串。不包括GETPOST參數以及域名。

例如,http://www.example.com/myapp/請求中,URLconf 將查找myapp/

http://www.example.com/myapp/?page=3請求中,URLconf 仍將查找myapp/

URLconf 不檢查請求的方法。換句話講,全部的請求方法—— 同一個URLPOSTGETHEAD等等 —— 都將路由到相同的函數。

 

2.1.4 捕獲的參數永遠是字符串

每一個捕獲的參數都做爲一個普通的Python字符串傳遞給視圖,不管正則表達式使用的是什麼匹配方式。例如,下面這行URLconf 中:

url(r'^articles/(?P<year>[0-9]{4})/$',views.year_archive),

views.year_archive() year 參數將是一個字符串

 

2.1.5 指定視圖參數的默認值

有一個方便的小技巧是指定視圖參數的默認值。 下面是一個URLconf 和視圖的示例:

# URLconf

from django.conf.urls import url

from . import views

 

urlpatterns = [

   url(r'^blog/$', views.page),

   url(r'^blog/page(?P<num>[0-9]+)/$', views.page),

]

 

# View (in blog/views.py)

def page(request, num="1"):

 

   ...

 

在上面的例子中,兩個URL模式指向同一個視圖views.page —— 可是第一個模式不會從URL 中捕獲任何值。若是第一個模式匹配,page() 函數將使用num參數的默認值"1"。若是第二個模式匹配,page() 將使用正則表達式捕獲的num 值。

 

2.1.6 Including other URLconfs

#At any point, your urlpatterns can「include」 other URLconf modules. This

#essentially 「roots」 a set of URLs belowother ones.

 

#For example, here’s an excerpt of theURLconf for the Django website itself.

#It includes a number of other URLconfs:

 

from django.conf.urls import include, url

 

urlpatterns = [

  url(r'^admin/', admin.site.urls),

  url(r'^blog/', include('blog.urls')),

]

 

2.2 傳遞額外的選項給視圖函數(瞭解)

URLconfs 具備一個鉤子,讓你傳遞一個Python 字典做爲額外的參數傳遞給視圖函數。

django.conf.urls.url() 函數能夠接收一個可選的第三個參數,它是一個字典,表示想要傳遞給視圖函數的額外關鍵字參數。

 

例如:

from django.conf.urls import url

from . import views

 

urlpatterns = [

   url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo':'bar'}),

]

在這個例子中,對於/blog/2005/請求,Django 將調用views.year_archive(request, year='2005', foo='bar')

 

這個技術在Syndication 框架中使用,來傳遞元數據和選項給視圖。

 

2.3 URL 的反向解析

在使用Django 項目時,一個常見的需求是得到URL 的最終形式,以用於嵌入到生成的內容中(視圖中和顯示給用戶的URL等)或者用於處理服務器端的導航(重定向等)。

人們強烈但願不要硬編碼這些URL(費力、不可擴展且容易產生錯誤)或者設計一種與URLconf 絕不相關的專門的URL 生成機制,由於這樣容易致使必定程度上產生過時的URL

換句話講,須要的是一個DRY 機制。除了其它有點,它還容許設計的URL 能夠自動更新而不用遍歷項目的源代碼來搜索並替換過時的URL

獲取一個URL 最開始想到的信息是處理它視圖的標識(例如名字),查找正確的URL 的其它必要的信息有視圖參數的類型(位置參數、關鍵字參數)和值。

Django 提供一個辦法是讓URL 映射是URL 設計惟一的地方。你填充你的URLconf,而後能夠雙向使用它:

根據用戶/瀏覽器發起的URL 請求,它調用正確的Django 視圖,並從URL 中提取它的參數須要的值。

根據Django 視圖的標識和將要傳遞給它的參數的值,獲取與之關聯的URL

第一種方式是咱們在前面的章節中一直討論的用法。第二種方式叫作反向解析URL、反向URL 匹配、反向URL 查詢或者簡單的URL 反查。

在須要URL 的地方,對於不一樣層級,Django 提供不一樣的工具用於URL 反查:

在模板中:使用url 模板標籤。

Python 代碼中:使用django.core.urlresolvers.reverse() 函數。

在更高層的與處理Django 模型實例相關的代碼中:使用get_absolute_url() 方法。

例子:

考慮下面的URLconf

from django.conf.urls import url

from . import views

 

urlpatterns = [

   #...

   url(r'^articles/([0-9]{4})/$', views.year_archive,name='news-year-archive'),

   #...

]

 

根據這裏的設計,某一年nnnn對應的歸檔的URL/articles/nnnn/

你能夠在模板的代碼中使用下面的方法得到它們:

 

<a href="{% url 'news-year-archive'2012 %}">2012 Archive</a>

<ul>

{% for yearvar in year_list %}

<li><a href="{% url'news-year-archive' yearvar %}">` yearvar `Archive</a></li>

{% endfor %}

</ul>

 

Python 代碼中,這樣使用:

from django.core.urlresolvers importreverse

from django.http importHttpResponseRedirect

 

def redirect_to_year(request):

    #...

   year = 2006

    #...

   return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

 

若是出於某種緣由決定按年歸檔文章發佈的URL應該調整一下,那麼你將只須要修改URLconf中的內容。

在某些場景中,一個視圖是通用的,因此在URL 和視圖之間存在多對一的關係。對於這些狀況,當反查URL 時,只有視圖的名字還不夠。

 

2.4 命名URL 模式

爲了完成上面例子中的URL 反查,你將須要使用命名的URL 模式。URL 的名稱使用的字符串能夠包含任何你喜歡的字符。不僅限制在合法的Python 名稱。

當命名你的URL 模式時,請確保使用的名稱不會與其它應用中名稱衝突。若是你的URL 模式叫作comment,而另一個應用中也有一個一樣的名稱,當你在模板中使用這個名稱的時候不能保證將插入哪一個URL

URL 名稱中加上一個前綴,好比應用的名稱,將減小衝突的可能。咱們建議使用myapp-comment 而不是comment

 

2.5 CBV

url(r'^login.html$',views.Login.as_view()),

============================

from django.views import View

class Login(View):

    

   def dispatch(self, request, *args, **kwargs):

       print('before')

       obj = super(Login,self).dispatch(request, *args, **kwargs)

       print('after')

       return obj

 

   def get(self,request):

       

       return render(request,'login.html')

 

   def post(self,request):

        print(request.POST.get('user'))

       return HttpResponse('Login.post')

 

視圖層之視圖函數(views)

一個視圖函數,簡稱視圖,是一個簡單的Python函數,它接受Web請求而且返回Web響應。響應能夠是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西均可以。不管視圖自己包含什麼邏輯,都要返回響應。代碼寫在哪裏也無所謂,只要它在你的Python目錄下面。除此以外沒有更多的要求了——能夠說「沒有什麼神奇的地方」。爲了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名爲views.py的文件中。

 

下面是一個返回當前日期和時間做爲HTML文檔的視圖:

from django.http import HttpResponse

import datetime

 

def current_datetime(request):

   now = datetime.datetime.now()

   html = "<html><body>It is now %s.</body></html>"% now

   return HttpResponse(html)

 

逐行閱讀上面的代碼:

首先,咱們從 django.http模塊導入了HttpResponse類,以及Pythondatetime庫。

接着,咱們定義了current_datetime函數。它就是視圖函數。每一個視圖函數都使用HttpRequest對象做爲第一個參數,而且一般稱之爲request

注意,視圖函數的名稱並不重要;不須要用一個統一的命名方式來命名,以便讓Django識別它。咱們將其命名爲current_datetime,是由於這個名稱可以精確地反映出它的功能。

這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每一個視圖函數都負責返回一個HttpResponse對象。       

 

HttpRequest對象

屬性:

'''

path       請求頁面的全路徑,不包括域名

method     請求中使用的HTTP方法的字符串表示。全大寫表示。例如

              if  req.method=="GET":

                        do_something()

              elifreq.method=="POST":

                        do_something_else()

GET:        包含全部HTTP GET參數的類字典對象

POST       包含全部HTTP POST參數的類字典對象

COOKIES:    包含全部cookies的標準Python字典對象;keysvalues都是字符串。

FILES      包含全部上傳文件的類字典對象;FILES中的每個Key都是<input type="file" name="" />標籤中

            name屬性的值,FILES中的每個value同時也是一個標準的python字典對象,包含下面三個Keys

            filename      上傳文件名,用字符串表示

            content_type:   上傳文件的Content Type

            content       上傳文件的原始內容

 

user       是一個django.contrib.auth.models.User對象,表明當前登錄的用戶。若是訪問用戶當前

            沒有登錄,user將被初始化爲django.contrib.auth.models.AnonymousUser的實例。你

            能夠經過useris_authenticated()方法來辨別用戶是否登錄:

            if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware時該屬性纔可用

session    惟一可讀寫的屬性,表明當前會話的字典對象;本身有激活Django中的session支持時該屬性纔可用。

'''

 

方法:

get_full_path()

注意:鍵值對的值是多個的時候,好比checkbox類型的input標籤,select標籤,須要用:

request.POST.getlist("hobby")

 

render 函數

render(request, template_name[, context]

結合一個給定的模板和一個給定的上下文字典,並返回一個渲染後的 HttpResponse 對象。

參數:

    request 用於生成響應的請求對象。

    template_name:要使用的模板的完整名稱,可選的參數

    context:添加到模板上下文的一個字典。默認是一個空字典。若是字典中的某個值是可調用的,視圖將在渲染模板以前調用它。

    content_type:生成的文檔要使用的MIME類型。默認爲DEFAULT_CONTENT_TYPE設置的值。

    status:響應的狀態碼。默認爲200

 

redirect 函數

參數能夠是:

一個模型:將調用模型的get_absolute_url()函數

一個視圖,能夠帶有參數:將使用urlresolvers.reverse來反向解析名稱

一個絕對的或相對的URL,將原封不動的做爲重定向的位置。

默認返回一個臨時的重定向;傳遞permanent=True能夠返回一個永久的重定向。

 

示例:

你能夠用多種方式使用redirect()函數。

傳遞一個對象

將調用get_absolute_url()方法來獲取重定向的URL

from django.shortcuts import redirect

 

def my_view(request):

   ...

   object = MyModel.objects.get(...)

   return redirect(object)

 

傳遞一個視圖的名稱

能夠帶有位置參數和關鍵字參數;將使用reverse()方法反向解析URL: 

def my_view(request):

   ...

   return redirect('some-view-name', foo='bar')

傳遞要重定向的一個硬編碼的URL

def my_view(request):

   ...

   return redirect('/some/url/')

也能夠是一個完整的URL

def my_view(request):

   ...

   return redirect('http://example.com/')

默認狀況下,redirect() 返回一個臨時重定向。以上全部的形式都接收一個permanent 參數;若是設置爲True,將返回一個永久的重定向:

 

def my_view(request):

   ...

   object = MyModel.objects.get(...)

   return redirect(object, permanent=True)

 

跳轉(重定向)應用

 

-----------------------------------url.py

 

 url(r"login",   views.login),

 url(r"yuan_back",   views.yuan_back),

 

-----------------------------------views.py

def login(req):

   if req.method=="POST":

       if 1:

           # return redirect("/yuan_back/")

           name="yuanhao"

 

           return render(req,"my backend.html",locals())

 

   return render(req,"login.html",locals())

 

def yuan_back(req):

 

   name="苑昊"

 

   return render(req,"my backend.html",locals())

 

-----------------------------------login.html

 

<form action="/login/"method="post">

   <p>姓名<inputtype="text" name="username"></p>

   <p>性別<inputtype="text" name="sex"></p>

   <p>郵箱<inputtype="text" name="email"></p>

   <p><input type="submit"value="submit"></p>

</form>

-----------------------------------mybackend.html

<h1>用戶` name `你好</h1>

 

注意:renderredirect的區別:

1 if 頁面須要模板語言渲染,須要的將數據庫的數據加載到html,那麼render方法則不會顯示這一部分。

2 the most important: url沒有跳轉到/yuan_back/,而是還在/login/,因此當刷新後又得從新登陸。

 

模板層(template)

你可能已經注意到咱們在例子視圖中返回文本的方式有點特別。 也就是說,HTML被直接硬編碼在 Python代碼之中。

def current_datetime(request):

   now = datetime.datetime.now()

   html = "<html><body>It is now%s.</body></html>" % now

   return HttpResponse(html)

儘管這種技術便於解釋視圖是如何工做的,但直接將HTML硬編碼到你的視圖裏卻並非一個好主意。 讓咱們來看一下爲何:

對頁面設計進行的任何改變都必須對Python 代碼進行相應的修改。 站點設計的修改每每比底層 Python 代碼的修改要頻繁得多,所以若是能夠在不進行 Python 代碼修改的狀況下變動設計,那將會方便得多。

Python 代碼編寫和 HTML 設計是兩項不一樣的工做,大多數專業的網站開發環境都將他們分配給不一樣的人員(甚至不一樣部門)來完成。設計者和HTML/CSS的編碼人員不該該被要求去編輯Python的代碼來完成他們的工做。

程序員編寫 Python代碼和設計人員製做模板兩項工做同時進行的效率是最高的,遠勝於讓一我的等待另外一我的完成對某個既包含 Python又包含 HTML 的文件的編輯工做。

基於這些緣由,將頁面的設計和Python的代碼分離開會更乾淨簡潔更容易維護。 咱們可使用 Django 模板系統 (Template System)來實現這種模式,這就是本章要具體討論的問題。

python的模板:HTML代碼+模板語法

模版包括在使用時會被值替換掉的 變量,和控制模版邏輯的 標籤。

def current_time(req):

    #================================原始的視圖函數

    #import datetime

    #now=datetime.datetime.now()

    #html="<html><body>如今時刻:<h1>%s.</h1></body></html>" %now

 

    #================================django模板修改的視圖函數

    #from django.template import Template,Context

    #now=datetime.datetime.now()

    #t=Template('<html><body>如今時刻是:<h1>`current_date`</h1></body></html>')

    ##t=get_template('current_datetime.html')

    #c=Context({'current_date':str(now)})

    #html=t.render(c)

    #return HttpResponse(html)

 

    #另外一種寫法(推薦)

   import datetime

   now=datetime.datetime.now()

   return render(req, 'current_datetime.html',{'current_date':str(now)[:19]})

 

模板語法之變量

Django 模板中遍歷複雜數據結構的關鍵是句點字符  .

語法: 

`var_name`

views

def index(request):

   import datetime

   s="hello"

   l=[111,222,333]    # 列表

   dic={"name":"yuan","age":18}  # 字典

   date = datetime.date(1993, 5, 2)  # 日期對象

 

   class Person(object):

       def __init__(self,name):

           self.name=name

 

   person_yuan=Person("yuan") # 自定義類對象

   person_egon=Person("egon")

   person_alex=Person("alex")

 

   person_list=[person_yuan,person_egon,person_alex]

 

 

   returnrender(request,"index.html",{"l":l,"dic":dic,"date":date,"person_list":person_list})

template

<h4>`s`</h4>

<h4>列表:` l`.`0 `</h4>

<h4>列表:` l`.`2 `</h4>

<h4>字典:` dic`.`name `</h4>

<h4>日期:` date`.`year `</h4>

<h4>類對象列表:` person_list`.`0`.`name `</h4>

注意:句點符也能夠用來引用對象的方法(無參數方法)

<h4>字典:` dic`.`name`.`upper `</h4>

 

模板之過濾器

語法:

{{obj|filter__name:param}}

Default

若是一個變量是false或者爲空,使用給定的默認值。不然,使用變量的值。例如:

{{ value|default:"nothing" }}

 

length

返回值的長度。它對字符串和列表都起做用。例如:

{{ value|length }}

若是 value ['a', 'b', 'c', 'd'],那麼輸出是 4

 

filesizeformat

將值格式化爲一個 「人類可讀的」文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如:

{{ value|filesizeformat }}

若是 value 123456789,輸出將會是 117.7 MB。  

 

date

若是value=datetime.datetime.now()

{{ value|date:"Y-m-d" }}

 

slice

若是value="hello world"

{{ value|slice:"2:-1" }}

truncatechars

 

若是字符串字符多於指定的字符數量,那麼會被截斷。截斷的字符串將以可翻譯的省略號序列(「...」)結尾。

參數:要截斷的字符數

例如:

{{ value|truncatechars:9 }}

若是value是「Joel a >,輸出將爲「Joel i ...」。

 

safe

Django的模板中會對HTML標籤和JS等語法標籤進行自動轉義,緣由顯而易見,這樣是爲了安全。可是有的時候咱們可能不但願這些HTML元素被轉義,好比咱們作一個內容管理系統,後臺添加的文章中是通過修飾的,這些修飾多是經過一個相似於FCKeditor編輯加註了HTML修飾符的文本,若是自動轉義的話顯示的就是保護HTML標籤的源文件。爲了在Django中關閉HTML的自動轉義有兩種方式,若是是一個單獨的變量咱們能夠經過過濾器「|safe」的方式告訴Django這段代碼是安全的沒必要轉義。好比:

 

value="<a href="">點擊</a>"

{{ value|safe}}

 

模板之標籤 

標籤看起來像是這樣的: {% tag%}。標籤比變量更加複雜:一些在輸出中建立文本,一些經過循環或邏輯來控制流程,一些加載其後的變量將使用到的額外信息到模版中。

一些標籤須要開始和結束標籤 (例如{% tag %} ...標籤內容 ... {% endtag %})。

 

for標籤

遍歷每個元素:

 

{% for person in person_list %}

   <p>` person`.`name `</p>

{% endfor %}

能夠利用{% for obj inlist reversed %}反向完成循環。

遍歷一個字典:

{% for key,val in dic.items %}

   <p>` key `:` val `</p>

{% endfor %}

注:循環序號能夠經過{{forloop}}顯示  

forloop.counter        The current iteration of the loop (1-indexed)

forloop.counter0    Thecurrent iteration of the loop (0-indexed)

forloop.revcounter  The number ofiterations from the end of the loop (1-indexed)

forloop.revcounter0 The number ofiterations from the end of the loop (0-indexed)

forloop.first           True if this is thefirst time through the loop

forloop.last            True if this is thelast time through the loop

 

for ... empty

for 標籤帶有一個可選的{% empty %} 從句,以便在給出的組是空的或者沒有被找到時,能夠有所操做。

{% for person in person_list %}

   <p>` person`.`name `</p>

{% empty %}

   <p>sorry,no person here</p>

{% endfor %}

 

if 標籤

{% if %}會對一個變量求值,若是它的值是「True」(存在、不爲空、且不是boolean類型的false值),對應的內容塊會輸出。

{% if num > 100 or num < 0 %}

   <p>無效</p>

{% elif num > 80 and num < 100 %}

   <p>優秀</p>

{% else %}

   <p>湊活吧</p>

{% endif %}

 

with

使用一個簡單地名字緩存一個複雜的變量,當你須要使用一個「昂貴的」方法(好比訪問數據庫)不少次的時候是很是有用的

例如:

{% with total=business.employees.count %}

   ` total ` employee{{ total|pluralize }}

{% endwith %}

csrf_token

 

這個標籤用於跨站請求僞造保護

 

自定義標籤和過濾器

1、在settings中的INSTALLED_APPS配置當前app,否則django沒法找到自定義的simple_tag.

2、在app中建立templatetags模塊(模塊名只能是templatetags)

3、建立任意 .py 文件,如:my_tags.py

from django import template

from django.utils.safestring import mark_safe

 

register = template.Library()   #register的名字是固定的,不可改變

 

@register.filter

def filter_multi(v1,v2):

    return  v1 * v2

<br>

@register.simple_tag

def simple_tag_multi(v1,v2):

    return  v1 * v2

<br>

@register.simple_tag

def my_input(id,arg):

    result = "<inputtype='text' id='%s' class='%s' />" %(id,arg,)

    return mark_safe(result)

 

4、在使用自定義simple_tagfilterhtml文件中導入以前建立的 my_tags.py

{% load my_tags %}

5、使用simple_tagfilter(如何調用)

-------------------------------.html

{% load xxx %} 

     

# num=12

{{ num|filter_multi:2 }} #24

 

{{num|filter_multi:"[22,333,4444]" }}

 

{% simple_tag_multi 2 5 %}  參數不限,但不能放在if for語句中

{% simple_tag_multi num 5 %}

注意:filter能夠用在if等語句後,simple_tag不能夠

{% if num|filter_multi:30 > 100 %}

    {{num|filter_multi:30 }}

{% endif %}

 

模板繼承 (extend)

Django模版引擎中最強大也是最複雜的部分就是模版繼承了。模版繼承可讓您建立一個基本的「骨架」模版,它包含您站點中的所有元素,而且能夠定義可以被子模版覆蓋的 blocks

經過從下面這個例子開始,能夠容易的理解模版繼承:

<!DOCTYPE html>

<html>

<head>

   <link rel="stylesheet" href="style.css" />

   <title>{% block title %}My amazing site{%/span> endblock%}</title>

</head>

 

<body>

   <div id="sidebar">

       {% block sidebar %}

       <ul>

           <li><a href="/">Home</a></li>

           <li><a href="/blog/">Blog</a></li>

       </ul>

       {% endblock %}

    </div>

 

   <div id="content">

       {% block content %}{% endblock %}

   </div>

</body>

</html>

 

這個模版,咱們把它叫做base.html 它定義了一個能夠用於兩列排版頁面的簡單HTML骨架。「子模版」的工做是用它們的內容填充空的blocks

在這個例子中, block 標籤訂義了三個能夠被子模版內容填充的block block 告訴模版引擎: 子模版可能會覆蓋掉模版中的這些位置。

子模版可能看起來是這樣的:

{% extends "base.html" %}

 

{% block title %}My amazing blog{% endblock%}

 

{% block content %}

{% for entry in blog_entries %}

   <h2>` entry`.`title `</h2>

   <p>` entry`.`body `</p>

{% endfor %}

{% endblock %}

extends 標籤是這裏的關鍵。它告訴模版引擎,這個模版「繼承」了另外一個模版。當模版系統處理這個模版時,首先,它將定位父模版——在此例中,就是「base.html」。

那時,模版引擎將注意到base.html 中的三個 block 標籤,並用子模版中的內容來替換這些block。根據 blog_entries 的值,輸出可能看起來是這樣的:

<!DOCTYPE html>

<html>

<head>

   <link rel="stylesheet" href="style.css" />

   <title>My amazing blog</title>

</head>

 

<body>

   <div id="sidebar">

       <ul>

           <li><a href="/">Home</a></li>

           <li><a href="/blog/">Blog</a></li>

       </ul>

   </div>

 

   <div id="content">

       <h2>Entry one</h2>

       <p>This is my first entry.</p>

 

       <h2>Entry two</h2>

       <p>This is my second entry.</p>

   </div>

</body>

</html>

請注意,子模版並無定義sidebar block,因此係統使用了父模版中的值。父模版的 {% block %} 標籤中的內容老是被用做備選內容(fallback)。

 

 

 

這種方式使代碼獲得最大程度的複用,而且使得添加內容到共享的內容區域更加簡單,例如,部分範圍內的導航。

這裏是使用繼承的一些提示:

若是你在模版中使用 {%extends %} 標籤,它必須是模版中的第一個標籤。其餘的任何狀況下,模版繼承都將沒法工做。

base模版中設置越多的 {% block %} 標籤越好。請記住,子模版沒必要定義所有父模版中的blocks,因此,你能夠在大多數blocks中填充合理的默認內容,而後,只定義你須要的那一個。多一點鉤子總比少一點好。

若是你發現你本身在大量的模版中複製內容,那可能意味着你應該把內容移動到父模版中的一個 {% block %} 中。

If you need to get the content of the blockfrom the parent template, the ` block`.`super ` variable will do the trick.This is useful if you want to add to the contents of a parent block instead ofcompletely overriding it. Data inserted using ` block`.`super ` will not beautomatically escaped (see the next section), since it was already escaped, ifnecessary, in the parent template.

 

爲了更好的可讀性,你也能夠給你的{% endblock %} 標籤一個 名字 。例如:

{% block content %}

...

{% endblock content %}

在大型模版中,這個方法幫你清楚的看到哪個  {% block %} 標籤被關閉了。

 

最後,請注意您並不能在一個模版中定義多個相同名字的 block 標籤。這個限制的存在是由於block標籤的做用是「雙向」的。這個意思是,block標籤不只提供了一個坑去填,它還在 _父模版_中定義了填坑的內容。若是在一個模版中有兩個名字同樣的 block 標籤,模版的父模版將不知道使用哪一個block的內容

相關文章
相關標籤/搜索