被解放的姜戈03 所謂伊人

被解放的姜戈03 所謂伊人html

 

做者:Vamei 出處:http://www.cnblogs.com/vamei 歡迎轉載,也請保留這段聲明。謝謝!數據庫

 

在以前的程序中,咱們直接生成一個字符串,做爲http回覆,返回給客戶端。這一過程當中使用了django.http.HttpResponse()。django

在這樣的一種回覆生成過程當中,咱們實際上將數據和視圖的格式混合了到上面的字符串中。看似方便,卻爲咱們的管理帶來困難。想像一個成熟的網站,其顯示格式會有許多重複的地方。若是能夠把數據和視圖格式分離,就能夠重複使用同一視圖格式了。編程

Django中自帶的模板系統,能夠將視圖格式分離出來,做爲模板使用。這樣,不但視圖能夠容易修改,程序也會顯得美觀大方。post

「她是我心中最美的人」,姜戈對德國人說。網站

 

模板初體驗

咱們拿一個獨立的templay.html文件做爲模板。它放在templates/west/文件夾下。文件系統的結構如今是:this

mysite/
├── mysite
├── templates
│   └── west
└── west

 

templay.html文件的內容是:url

<h1>{{ label }}</h1>

能夠看到,這個文件中,有一個奇怪的雙括號包起來的陌生人。這就是咱們將來數據要出現的地方。而相關的格式控制,即<h1>標籤,則已經標明在該模板文件中。spa

 

咱們須要向Django說明模板文件的搜索路徑,修改mysite/settings.py,添加:code

# Template dir TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates/west/'), )

若是還有其它的路徑用於存放模板,能夠增長該元組中的元素,以便Django能夠找到須要的模板。

 

咱們如今修改west/views.py,增長一個新的對象,用於向模板提交數據:

複製代碼
# -*- coding: utf-8 -*- #from django.http import HttpResponse from django.shortcuts import render def templay(request): context = {} context['label'] = 'Hello World!' return render(request, 'templay.html', context)
複製代碼

能夠看到,咱們這裏使用render來替代以前使用的HttpResponse。render還使用了一個詞典context做爲參數。這就是咱們的數據。

context中元素的鍵值爲'label',正對應剛纔的「陌生人」的名字。這樣,該context中的‘label’元素值,就會填上模板裏的坑,構成一個完整的http回覆。

 

做爲上節內容的一個小練習,自行修改west/urls.py,讓http://127.0.0.1:8000/west/templay的URL請求能夠找到相應的view對象。

 

訪問http://127.0.0.1:8000/west/templay,能夠看到頁面:

 

「我給你講個故事吧,勇士拯救公主的故事」,德國人說。

 

流程

再來回顧一下整個流程。west/views.py中的templay()在返回時,將環境數據context傳遞給模板templay.html。Django根據context元素中的鍵值,將相應數據放入到模板中的對應位置,生成最終的http回覆。

這一模板系統能夠與Django的其它功能相互合做。上一回,咱們從數據庫中提取出了數據。若是將數據庫中的數據放入到context中,那麼就能夠將數據庫中的數據傳送到模板。

修改上次的west/views.py中的staff:

def staff(request): staff_list = Character.objects.all() staff_str = map(str, staff_list) context = {'label': ' '.join(staff_str)} return render(request, 'templay.html', context)

 

練習: 顯示上面的staff頁面。

 

「勇士翻太高山,並不是由於他不懼怕。」

 

循環與選擇

Django實際上提供了豐富的模板語言,能夠在模板內部有限度的編程,從而更方便的編寫視圖和傳送數據。

咱們下面體驗一下最多見的循環與選擇。

 

上面的staff中的數據其實是一個數據容器,有三個元素。剛纔咱們將三個元素鏈接成一個字符串傳送。

實際上,利用模板語言,咱們能夠直接傳送數據容器自己,再循環顯示。修改staff()爲:

def staff(request): staff_list = Character.objects.all() return render(request, 'templay.html', {'staffs': staff_list})

從數據庫中查詢到的三個對象都在staff_list中。咱們直接將staff_list傳送給模板。

將模板templay.html修改成:

{% for item in staffs %} <p>{{ item.id }}, {{item}}</p> {% endfor %}

咱們以相似於Python中for循環的方式來定義模板中的for,以顯示staffs中的每一個元素。

還能夠看到,對象.屬性名的引用方式能夠直接用於模板中。

 

選擇結構也與Python相似。根據傳送來的數據是否爲True,Django選擇是否顯示。使用方式以下:

複製代碼
{% if condition1 %}
   ... display 1
{% elif condiiton2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}
複製代碼

其中的elif和else和Python中同樣,是能夠省略的。

 

「勇士屠殺惡龍,並不是由於他不恐懼。」

 

模板繼承

模板能夠用繼承的方式來實現複用。咱們下面用templay.html來繼承base.html。這樣,咱們可使用base.html的主體,只替換掉特定的部分。

新建templates/west/base.html:

複製代碼
<html> <head> <title>templay</title> </head> <body> <h1>come from base.html</h1> {% block mainbody %} <p>original</p> {% endblock %} </body> </html>
複製代碼

該頁面中,名爲mainbody的block標籤是能夠被繼承者們替換掉的部分。

 

咱們在下面的templay.html中繼承base.html,並替換特定block:

複製代碼
{% extends "base.html" %} {% block mainbody %} {% for item in staffs %} <p>{{ item.id }},{{ item.name }}</p> {% endfor %} {% endblock %}
複製代碼

第一句說明templay.html繼承自base.html。能夠看到,這裏相同名字的block標籤用以替換base.html的相應block。

 

「勇士穿過地獄火焰,由於,她值得。」

 

總結

使用模板實現視圖分離。

數據傳遞,模板變量,模板循環與選擇,模板繼承。

 

姜戈靜靜的說,「我懂得他的感覺。」

 

歡迎閱讀「被解放的姜戈」系列文章。

相關文章
相關標籤/搜索