2015年7月10日 星期五

Python筆記:Django(3) Views&Template

Views

當 Django 收到一個 HTTP request 時,會先確認該 request 的 URI 應該對應到哪個 view,並把 request 交給它。View 要負責處理這個 request,並回傳一個 HTTP response.

簡單來說在Django 中,每個 view 其實就是一個 function。這個 function 接受一個 request 參數,回傳django.http.HttpResponse 物件。

要完成一個可以回應給使用者的頁面,主要有兩個步驟:

1. 設定urls.py
2. 撰寫view function

設定urls.py

在urls.py 新增一個 URL pattern,讓 Django 知道如何把網址導向至 view 的 function:

from django.conf.urls import patterns, include, url
from django.contrib import admin
from stores.views import home # 從views.py中匯入home這個function

urlpatterns = patterns(
'',
url(r'^$', home, name='home'),   # 加入此行
url(r'^admin/', include(admin.site.urls)),
)

對r’^home/$’ 做個解釋,這是Python中正規表達式的寫法,^號代表配對開始,$號代表配對結束,所以這行是說網域後的字串要”完全”等於/home/才算配對成功,home前面並沒有寫出/,這是因為Django預設會幫你加上這個slash。另外,代表配對結束,使用標準路徑來import

如果寫成url(r'^home/$', home)就是告訴Django,看到網域後面出現/home/就去call views.py裡面的functionhere

撰寫view function

在子目錄stores下面產生一個views.py並完成home這個function.

#stores/views.py
from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

Home function: request是一個有關使用者請求的物件HttpRequest,要這樣想,有求才有應,有問才有答,你的回應一定伴隨著一個要求,所以任何action都把request設為第一個參數吧。第二個參數是 template 的位置。HttpResponse會負責處理 template,產生一個合法的 HTML 檔案,並依此建立 HTTP response。

HttpResponse物件,參數可以是一個字串或一個完整的html.

別忘了要在settings中加入stores這個app. 執行runserver後就會發現原本的畫面變成我們設定的畫面了.如果想輸出中文的話…
Ex.

# -*- coding: utf-8 -*-  #加入此行

from django.http import HttpResponse

def here(request):
    return HttpResponse('我在這!')

Template

Template的概念是預先完成骨架,會預先在上面挖幾個洞(變數),再根據接收到的資料把肉(參數)填上去.關於使用模版的理由,Django Book列出了以下幾點:

  1. Any change to the design of the page requires a change to the Python code. The design of a site tends to change far more frequently than the underlying Python code, so it would be convenient if the design could change without needing to modify the Python code.

  2. Writing Python code and designing HTML are two different disciplines, and most professional Web development environments split these responsibilities between separate people (or even separate departments). Designers and HTML/CSS coders shouldn’t be required to edit Python code to get their job done.

  3. It’s most efficient if programmers can work on Python code and designers can work on templates at the same time, rather than one person waiting for the other to finish editing a single file that contains both Python and HTML.

就是想要將html和python code分開來寫,不但不會混亂還能同時進行。更重要的是,改一邊可以不用動到另一邊。這邊舉一個範例是如果不使用Template的話,想把HTML的內容呈現出來,會寫在views.py裡.
Ex.

# .../views.py

from datetime import datetime
from django.http import HttpResponse


def hello_world(request):
    output = """
        <!DOCTYPE html>
        <html>
            <head>
            </head>
            <body>
                Hello World! <em style="color:LightSeaGreen;">{current_time}</em>
            </body>
        </html>
    """.format(current_time=datetime.now())

    return HttpResponse(output)

創建與填寫Template

實作一樣有兩個步驟

1. 創建Template
2. 填寫Template

一個模版主要由下表所列的元素構成:
enter image description here

Ex.

$ python manage.py shell

>>> from django import template
>>> t = template.Template('I love {{ name }}.')
>>> c = template.Context({'name':'SNSD'})
>>> print t.render(c)
I love SNSD.

name必須在{{}}裡面才會被當成變量。利用Context物件來填寫他,字典的key會對應到相同名稱的變量,而值會成該變量的值,簡單來說就是在模版中看到{{ name }}變量就替喚為字串’SNSD’。

Template物件中的render方法執行的就是填寫的動作,會將Context的鍵找到對應的變量位置並且填入該鍵對應的值。

建立資料夾Template

在stores中新增一個資料夾templates專門放置模版。接著在templates目錄下新增一個檔案home.html,然後我們將模版內容移到home.html中.架構則如下所示.

Dinbendon
├── Dinbendon
│ ├── settings.py
│ ├── __init__.py
│ ├── urls.py
│ └── wsgi.py
├── stores
│ ├── migrations
│ │ └── __init__.py
│ ├── templates
│ │ └──home.html
│ ├── __init__.py
│ ├── admin.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
└── manage.py

建立第一個 Template home

{# stores/templates/home.html #}
<!DOCTYLE html>
<html>
<head>
<meta charset="utf-8">
<title>訂便當</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>

<body>
<nav class="navbar navbar-default navbar-static-top" role="navigation">
<div class="container">
  <div class="navbar-header">
    <a class="navbar-brand" href="{% url 'home' %}">午餐系統</a>
  </div>
</div>
</nav>
</body>
</html>

django.shortcuts.render

Render:產生 HttpResponse 物件。Django的模板系統的基本規則:寫模板,創建template對象,創建context,調用render()方法。

我們 import 了 django.shortcuts.render,這個 function 可以幫助我們讀取 template 之後,把變數以 python dictionary 的方式傳入 template 當中,最後再 render 出來並且回傳到瀏覽器中。
(範例可以參考在上面的”撰寫view function“)

{% url ‘home’ %} 是什麼?

這叫 template tag。因為不能在 template 中寫 Python(all hail PHP!),所以如果你需要在 template 中使用任何邏輯(JavaScript 不算),就必須使用 template tags。

Django 的 template tag 語法是下面這樣:

{% tag_name [ argument ... ] %}

所以上面那個例子中,我們呼叫了 url 這個 tag,並傳入一個參數’home’。這個 tag 會幫你找到名稱為 home 的 URL pattern,並輸出該 pattern 對應的網址。在這裡,輸出的就會是 /。

成果:
enter image description here

參考:
http://dokelung-blog.logdown.com/posts/220315-django-notes-3-templates
http://djangogirlstaipei.gitbooks.io/django-girls-taipei-tutorial/content/django/templates.html

沒有留言:

張貼留言