<source id="4vppl"><ins id="4vppl"></ins></source>
<u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
<object id="4vppl"></object>
  • <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

    <object id="4vppl"></object>
    <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

      <i id="4vppl"><thead id="4vppl"></thead></i>

      <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>

      當前位置:首頁 > 網站舊欄目 > 學習園地 > 設計軟件教程 > 翻譯www.djangobook.com之第四章:Django模板系統

      翻譯www.djangobook.com之第四章:Django模板系統
      2010-01-13 23:35:21  作者:  來源:
      前面的章節我們看到如何在視圖中返回HTML,但是HTML是硬編碼在Python代碼中的
      這會導致幾個問題:
      1,顯然,任何頁面的改動會牽扯到Python代碼的改動
      網站的設計改動會比Python代碼改動更頻繁,所以如果我們將兩者分離開會更方便
      2,其次,寫后臺Python代碼與設計HTML是不同的工作,更專業的Web開發應該將兩者分開
      頁面設計者和HTML/CSS程序員不應該編輯Python代碼,他們應該與HTML打交道
      3,程序員寫Python代碼同時頁面設計者寫HTML模板會更高效,而不是一個人等待另一個人編輯同樣的文件
      因此,使用Django的模板系統分離設計和Python代碼會更干凈更易維護

      模板系統基礎
      Django模板是一個string文本,它用來分離一個文檔的展現和數據
      模板定義了placeholder和表示多種邏輯的tags來規定文檔如何展現
      通常模板用來輸出HTML,但是Django模板也能生成其它基于文本的形式
      讓我們來看看一個簡單的模板例子:
      Java代碼 復制代碼
      1. <html>   
      2. <head><title>Ordering notice</title></head>   
      3. <body>   
      4. <p>Dear {{ person_name }},</p>   
      5. <p>Thanks for placing an order from {{ company }}. It's scheduled to   
      6. ship on {{ ship_date|date:"F j, Y" }}.</p>   
      7. <p>Here are the items you've ordered:</p>   
      8. <ul>   
      9. {% for item in item_list %}   
      10. <li>{{ item }}</li>   
      11. {% endfor %}   
      12. </ul>   
      13. {% if ordered_warranty %}   
      14. <p>Your warranty information will be included in the packaging.</p>   
      15. {% endif %}   
      16. <p>Sincerely,<br />{{ company }}</p>   
      17. </body>   
      18. </html>  

      這個模板本質上是HTML,但是夾雜了一些變量和模板標簽:
      1,用{{}}包圍的是變量,如{{person_name}},這表示把給定變量的值插入,如何指定這些變量的值我們即將說明
      2,用{%%}包圍的是塊標簽,如{%if ordered_warranty%}
      塊標簽的含義很豐富,它告訴模板系統做一些事情
      在這個例子模板中包含兩個塊標簽:for標簽表現為一個簡單的循環結構,讓你按順序遍歷每條數據
      if標簽則表現為邏輯的if語句
      在這里,上面的標簽檢查ordered_warranty變量的值是否為True
      如果是True,模板系統會顯示{%if ordered_warranty%}和{%endif%}之間的內容
      否則,模板系統不會顯示這些內容
      模板系統也支持{%else%}等其它邏輯語句
      3,上面還有一個過濾器的例子,過濾器是改變變量顯示的方式
      上面的例子中{{ship_date|date:"F j, Y"}}把ship_date變量傳遞給過濾器
      并給date過濾器傳遞了一個參數“F j, Y”,date過濾器以給定參數的形式格式化日期
      類似于Unix,過濾器使用管道字符“|”
      Django模板支持多種內建的塊標簽,并且你可以寫你自己的標簽

      使用模板系統
      在Python代碼中使用模板系統,請按照下面的步驟:
      1,用模板代碼創建一個Template對象
      Django也提供指定模板文件路徑的方式創建Template對象
      2,使用一些給定變量context調用Template對象的render()方法
      這將返回一個完全渲染的模板,它是一個string,其中所有的變量和塊標簽都會根據context得到值

      創建模板對象
      最簡單的方式是直接初始化它,Template類在django.template模塊中,初始化方法需要一個參數
      下面進入Python交互環境看看:
      Java代碼 復制代碼
      1. >>> from django.template import Template   
      2. >>> t = Template("My name is {{my_name}}.")   
      3. >>> print t  

      你將看到如下信息
      Java代碼 復制代碼
      1. <django.template.Template object at 0xb7d5f24c>  

      0xb7d5f24c每次都會改變,但是無所謂,它是Template對象的Python“identity”
      在這本書中,我們會在Python的交互式會話環境中展示一些示例。當你看到三個大于號'>>>',就可以確定是在交互環境中了。
      如果你從本書中拷貝代碼,記得不要拷貝這些大于號。
      當你創建Template對象,模板系統會編譯模板代碼,并準備渲染
      如果你的模板代碼有語法錯誤,調用Template()方法會觸發TemplateSyntaxError異常
      Java代碼 復制代碼
      1. >>> from django.template import Template   
      2. >>> t = Template('{%notatag%}')   
      3. Traceback (most recent call last):   
      4.     File "<stdin>", line 1, in ?   
      5.     ...   
      6.    django.template.TemplateSyntaxError: Invalid block tag: 'notatag'  

      系統觸發TemplateSyntaxError異常可能出于以下情況:
      1,不合法的塊標簽
      2,合法塊標簽接受不合法的參數
      3,不合法的過濾器
      4,合法過濾器接受不合法的參數
      5,不合法的模板語法
      6,塊標簽沒關

      渲染模板
      一旦你擁有一個Template對象,你可以通過給一個context來給它傳遞數據
      context是一個變量及賦予的值的集合,模板使用它來得到變量的值,或者對于塊標簽求值
      這個context由django.template模塊的Context類表示
      它的初始化函數有一個可選的參數:一個映射變量名和變量值的字典
      通過context調用Template對象的render()方法來填充模板,例如:
      Java代碼 復制代碼
      1. >>> from django.template import Context, Template   
      2. >>> t = Template("My name is {{name}}.")   
      3. >>> c = Context({"name""Stephane"})   
      4. >>> t.render(c)   
      5. 'My name is Stephane.'  

      變量名必須以字母(A-Z或a-z)開始,可以包含數字,下劃線和小數點,變量名大小寫敏感
      下面是一個模板編譯和渲染的例子,使用這章開始時的模板例子:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> raw_template = """<p>Dear {{ person_name }},</p>   
      3. ...   
      4. ... <p>Thanks for ordering {{ product }} from {{ company }}. It's scheduled to   
      5. ... ship on {{ ship_date|date:"F j, Y" }}.</p>   
      6. ...   
      7. ... {% if ordered_warranty %}   
      8. ... <p>Your warranty information will be included in the packaging.</p>   
      9. ... {% endif %}   
      10. ...   
      11. ... <p>Sincerely,<br />{{ company }}</p>"""   
      12. >>> t = Template(raw_template)   
      13. >>> import datetime   
      14. >>> c = Context({'person_name''John Smith',   
      15. ...     'product''Super Lawn Mower',   
      16. ...     'company''Outdoor Equipment',   
      17. ...     'ship_date': datetime.date(200942),   
      18. ...     'ordered_warranty': True})   
      19. >>> t.render(c)   
      20. "<p>Dear John Smith,</p>\n\n<p>Thanks for ordering Super Lawn Mower from Outdoor Equipment.   
      21. It's scheduled to ship on April 22009.</p>\n\n<p>Your warranty information will be included   
      22. in the packaging.</p>\n\n\n<p>Sincerely,<br />Outdoor Equipment</p>"  

      讓我們來看看都做了些什么:
      1,我們import Template和Context類,它們都在django.template模塊里面
      2,我們把模板文本存儲在raw_template變量里,我們使用"""來構建string,它可以跨越多行
      3,我們創建模板對象t,并給Template類的初始化函數傳遞raw_template變量
      4,我們從Python的標準庫import datetime模塊,下面會用到它
      5,我們創建一個context對象c,它的初始化函數使用一個映射變量名和變量值的字典
      例如我們指定person_name的值為'John Smith',product的值為'Super Lawn Mower'等等
      6,最后,我們調用模板對象的render()方法,參數為context對象c
      這將返回渲染后的模板,將模板中的變量值替換并計算塊標簽的結果
      如果你剛接觸Python,你可能會問為什么輸出中包含了新行字符'\n'而不是換行
      這是因為Python交互環境中調用t.render(c)會顯示string的representation而不是string的值
      如果你想看到換行而不是'\n',使用print t.render(c)即可
      上面是使用Django模板系統的基礎,只是創建一個模板對象和context對象然后調用render()方法
      同一個模板,多個context的情況:
      一旦你創建了一個模板對象,你可以渲染多個context,例如:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> t = Template('Hello, {{ name }}')   
      3. >>> print t.render(Context({'name''John'}))   
      4. Hello, John   
      5. >>> print t.render(Context({'name''Julie'}))   
      6. Hello, Julie   
      7. >>> print t.render(Context({'name''Pat'}))   
      8. Hello, Pat  

      無論何時,你使用同一個模板來渲染多個context的話,創建一次Template對象然后調用render()多次會更高效
      Java代碼 復制代碼
      1. # Bad   
      2. for name in ('John''Julie''Pat'):   
      3.     t = Template('Hello, {{ name }}')   
      4.     print t.render(Context({'name': name}))   
      5. # Good   
      6. t = Template('Hello, {{ name }}')   
      7. for name in ('John''Julie''Pat'):   
      8.     print t.render(Context({'name': name}))  

      Django的模板解析非常快,在后臺,大部分的解析通過一個單獨的對正則表達式的調用來做
      這與基于XML的模板引擎形成鮮明對比,XML解析器比Django的模板渲染系統慢很多

      Context變量查找
      上面的例子中,我們給模板context傳遞了簡單的值,大部分是string,以及一個datetime.date
      盡管如此,模板系統優雅的處理更復雜的數據結構,如列表,字典和自定義對象
      在Django模板系統中處理復雜數據結構的關鍵是使用(.)字符
      使用小數點來得到字典的key,屬性,對象的索引和方法
      下面通過例子來解釋,通過(.)訪問字典的key:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> person = {'name''Sally''age''43'}   
      3. >>> t = Template('{{ person.name }} is {{ person.age }} years old.')   
      4. >>> c= Context({'person': person})   
      5. >>> t.render(c)   
      6. 'Sally is 43 years old.'  

      通過(.)來訪問對象的屬性:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> import datetime   
      3. >>> d = datetime.date(199352)   
      4. >>> d.year   
      5. 1993  
      6. >>> d.month   
      7. 5  
      8. >>> d.day   
      9. 2  
      10. >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')   
      11. >>> c = Context({'date': d})   
      12. >>> t.render(c)   
      13. 'The month is 5 and the year is 1993.'  

      下面的例子使用一個自定義類:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> class Person(object):   
      3. ...    def __init__(self, first_name, last_name):   
      4. ...        self.first_name, self.last_name = first_name, last_name   
      5. >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')   
      6. >>> c = Context({'person': Person('John''Smith')})   
      7. >>> t.render(c)   
      8. 'Hello, John Smith.'  

      小數點也可以用來調用列表的索引:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> t = Template('Item 2 is {{ items.2 }}.')   
      3. >>> c = Contexst({'items': ['apples''bananas''carrots']})   
      4. >>> t.render(c)   
      5. 'Item 2 is carrots.'  

      負數的列表索引是不允許的,例如模板變量{{ items.-1 }}將觸發TemplateSyntaxError
      最后小數點還可以用來訪問對象的方法,例如Python的string有upper()和isdigit()方法:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> t = Template('{{ var }} -- {{var.upper }} -- {{ var.isdigit }}')   
      3. >>> t.render(Context({'var''hello'}))   
      4. 'hello -- HELLO -- False'  
      5. >>> t.render(Context({'var''123'}))   
      6. '123 - 123 - True'  

      注意,調用方法時你不能加括號,你也不能給方法傳遞參數
      你只能調用沒有參數的方法,后面我們會解釋這些
      總結一下,當模板系統遇到變量名里有小數點時會按以下順序查找:
      1,字典查找,如foo["bar"]
      2,屬性查找,如foo.bar
      3,方法調用,如foo.bar()
      3,列表的索引查找,如foo[bar]
      小數點可以多級縱深查詢,例如{{ person.name.upper }}表示字典查詢person['name']然后調用upper()方法
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> person = {'name''Sally''age''43'}   
      3. >>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')   
      4. >>> c = Context({'person': person})   
      5. >>> t.render(c)   
      6. 'SALLY is 43 years old.'  


      關于方法調用
      方法調用要比其他的查詢稍微復雜一點,下面是需要記住的幾點:
      1,在方法查詢的時候,如果一個方法觸發了異常,這個異常會傳遞從而導致渲染失
      敗,但是如果異常有一個值為True的silent_variable_failure屬性,這個變量會渲染成空string:
      Java代碼 復制代碼
      1. >>> t = Template("My name is {{ person.first_name }}.")   
      2. >>> class PersonClas3:   
      3. ...     def first_name(self):   
      4. ...         raise AssertionError, "foo"  
      5. >>> p = PersonClass3()   
      6. >>> t.render(Context({"person": p}))   
      7. Traceback (most recent call last):   
      8. ...   
      9. AssertionError: foo   
      10. >>> class SilentAssetionError(AssertionError):   
      11. ...     silent_variable_failure = True   
      12. >>> class PersonClass4:   
      13. ...     def first_name(self):   
      14. ...         raise SilentAssertionError   
      15. >>> p = PersonClass4()   
      16. >>> t.render(Context({"person": p}))   
      17. "My name is ."  

      2,方法調用僅僅在它沒有參數時起作用,否則系統將繼續查找下一個類型(列表索引查詢)
      3,顯然一些方法有副作用,讓系統訪問它們是很愚蠢的,而且很可能會造成安全性問
      題。
      例如你有一個BankAccount對象,該對象有一個delete()方法,模板系統不應該允許做下面的事情
      I will now delete this valuable data. {{ account.delete }}
      為了防止這種狀況,可以在方法里設置一個方法屬性alters_data
      如果設置了alters_data=True的話模板系統就不會執行這個方法:
      Java代碼 復制代碼
      1. def delete(self):   
      2.     # Delete the account   
      3. delete.alters_data = True  


      不合法的變量怎樣處理
      默認情況下如果變量不存在,模板系統會把它渲染成空string,例如:
      Java代碼 復制代碼
      1. >>> from django.template import Template, Context   
      2. >>> t = Template('Your name is {{ name }}.')   
      3. >>> t.render(Context())   
      4. 'Your name is .'  
      5. >>> t.render(Context({'var''hello'}))   
      6. 'Your name is .'  
      7. >>> t.render(Context({'NAME''hello'}))   
      8. 'Your name is .'  
      9. >>> t.render(Context({'Name''hello'}))   
      10. 'Your name is .'  

      系統會靜悄悄地顯示錯誤的頁面,而不是產生一個異常,因為這種情況通常是人為的錯誤。
      在現實情形下,一個web站點因為一個模板代碼語法的錯誤而變得不可用是不可接受的。
      我們可以通過設置Django配置更改Django的缺省行為,第10章擴展模板引擎會我們會討論這個

      玩玩Context對象
      大多數情況下你初始化Context對象會傳遞一個字典給Context()
      一旦你初始化了Context,你可以使用標準Python字典語法增減Context對象的items:
      Java代碼 復制代碼
      1. >>> from django.template import Context   
      2. >>> c = Context({"foo""bar"})   
      3. >>> c['foo']   
      4. 'bar'  
      5. >>> del c['foo']   
      6. >>> c['foo']   
      7. ''  
      8. >>> c['newvariable'] = 'hello'  
      9. >>> c['newvariable']   
      10. 'hello'  

      Context對象是一個stack,你可以push()和pop()
      如果你pop()的太多的話它將觸發django.template.ContextPopException:
      Java代碼 復制代碼
      1. >>> c = Context()   
      2. >>> c['foo'] = 'first level'  
      3. >>> c.push()   
      4. >>> c['foo'] = 'second level'  
      5. >>> c['foo']   
      6. 'second level'  
      7. >>> c.pop()   
      8. >>> c['foo']   
      9. 'first level'  
      10. >>> c['foo'] = 'overwritten'  
      11. >>> c['foo']   
      12. 'overwritten'  
      13. >>> c.pop()   
      14. Traceback (most recent call last):   
      15. ...   
      16. django.template.ContextPopException  

      第10章你會看到使用Context作為stack自定義模板標簽

      模板標簽和過濾器基礎
      我們已經提到模板系統使用內建的標簽和過濾器
      這里我們看看常見的,附錄6包含了完整的內建標簽和過濾器,你自己熟悉那個列表來了解可以做什么是個好主意

      if/else
      {% if %}標簽計算一個變量值,如果是“true”,即它存在、不為空并且不是false的boolean值
      系統則會顯示{% if %}和{% endif %}間的所有內容:
      Java代碼 復制代碼
      1. {% if today_is_weekend %}   
      2.     <p>Welcome to the weekend!</p>   
      3. {% else %}   
      4.     <p>Get back to work.</p>   
      5. {% endif %}  

      {% if %}標簽接受and,or或者not來測試多個變量值或者否定一個給定的變量,例如:
      Java代碼 復制代碼
      1. {% if athlete_list and coach_list %}   
      2.     Both athletes and coaches are available.   
      3. {% endif %}   
      4. {% if not athlete_list %}   
      5.     There are no athletes.   
      6. {% endif %}   
      7. {% if athlete_list or coach_list %}   
      8.     There are some athletes or some coaches.   
      9. {% endif %}   
      10. {% if not athlete_list or coach_list %}   
      11.     There are no athletes or there are some coaches.   
      12. {% endif %}   
      13. {% if athlete_list and not coach_list %}   
      14.     There are some athletes and absolutely no coaches.   
      15. {% endif %}  

      {% if %}標簽不允許同一標簽里同時出現and和or,否則邏輯容易產生歧義,例如下面的標簽是不合法的:
      Java代碼 復制代碼
      1. {% if athlete_list and coach_list or cheerleader_list %}  

      如果你想結合and和or來做高級邏輯,只需使用嵌套的{% if %}標簽即可:
      Java代碼 復制代碼
      1. {% if athlete_list %}   
      2.     {% if coach_list or cheerleader_list %}   
      3.         We have athletes, and either coaches or cheerleaders!   
      4.     {% endif %}   
      5. {% endif %}  

      多次使用同一個邏輯符號是合法的:
      Java代碼 復制代碼
      1. {% if athlete_list or coach_list or parent_list or teacher_list %}  

      沒有{% elif %}標簽,使用嵌套的{% if %}標簽可以做到同樣的事情:
      Java代碼 復制代碼
      1. {% if athlete_list %}   
      2.     <p>Here are the athletes: {{ athlete_list }}.</p>   
      3. {% else %}   
      4.     <p>No athletes are available.</p>   
      5.     {% if coach_list %}   
      6.         <p>Here are the coaches: {{ coach_list }}.</p>   
      7.     {% endif %}   
      8. {% endif %}  

      確認使用{% endif %}來關閉{% if %}標簽,否則Django觸發TemplateSyntaxError

      for
      {% for %}標簽允許你按順序遍歷一個序列中的各個元素
      Python的for語句語法為for X in Y,X是用來遍歷Y的變量
      每次循環模板系統都會渲染{% for %}和{% endfor %}之間的所有內容
      例如,顯示給定athlete_list變量來顯示athlete列表:
      Java代碼 復制代碼
      1. <ul>   
      2. {% for athlete in athlete_list %}   
      3.     <li>{{ athlete.name }}</li>   
      4. {% endfor %}   
      5. </ul>  

      在標簽里添加reversed來反序循環列表:
      Java代碼 復制代碼
      1. {% for athlete in athlete_list reversed %}   
      2. ...   
      3. {% endfor %}   
      4. {% for %}標簽可以嵌套:   
      5. {% for country in countries %}   
      6.     <h1>{{ country.name }}</h1>   
      7.     <ul>   
      8.     {% for city in country.city_list %}   
      9.         <li>{{ city }}</li>   
      10.     {% endfor %}   
      11.     </ul>   
      12. {% endfor %}  

      系統不支持中斷循環,如果你想這樣,你可以改變你想遍歷的變量來使得變量只包含你想遍歷的值
      類似的,系統也不支持continue語句,本章后面的“哲學和限制”會解釋設計的原則
      {% for %}標簽內置了一個forloop模板變量,這個變量含有一些屬性可以提供給你一些關于循環的信息
      1,forloop.counter表示循環的次數,它從1開始計數,第一次循環設為1,例如:
      Java代碼 復制代碼
      1. {% for item in todo_list %}   
      2.     <p>{{ forloop.counter }}: {{ item }}</p>   
      3. {% endfor %}  

      2,forloop.counter0類似于forloop.counter,但它是從0開始計數,第一次循環設為0
      3,forloop.revcounter表示循環中剩下的items數量,第一次循環時設為items總數,最后一次設為1
      4,forloop.revcounter0類似于forloop.revcounter,但它是表示的數量少一個,即最后一次循環時設為0
      5,forloop.first當第一次循環時值為True,在特別情況下很有用
      安徽新華電腦學校專業職業規劃師為你提供更多幫助【在線咨詢
      国产午夜福三级在线播放_亚洲精品成a人片在线观看_亚洲自慰一区二区三区_久久棈精品久久久久久噜噜
      <source id="4vppl"><ins id="4vppl"></ins></source>
      <u id="4vppl"><sub id="4vppl"><label id="4vppl"></label></sub></u>
      <object id="4vppl"></object>
    1. <u id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></u>

      <object id="4vppl"></object>
      <b id="4vppl"><sub id="4vppl"><tr id="4vppl"></tr></sub></b>

        <i id="4vppl"><thead id="4vppl"></thead></i>

        <thead id="4vppl"><li id="4vppl"><label id="4vppl"></label></li></thead>
        亚洲国产精品VA在线看黑人 | 最新国产在线观看精品 | 在线人成视频福利免费 | 亚洲国产日本欧美乱久久 | 日本亚洲中文字幕网 | 亚洲国产日韩综合久久精品 |