[part 3] 第一個 Django 應用

pardon110發表於2019-07-12

本節聚焦檢視,django 中的檢視更類似於其他框架的控制器,側重於資料渲染

概述

  • 框架 view 是 web 頁的一種"型別",它通常由指定函式和模板組成
  • 本 poll 應用由 index,detail,results三個展示頁,一個 vote動作組成
  • Django檢視表現為單一的可呼叫物件(函式,或檢視類方法),選擇檢視由來自請求的 url 決定,即 URLconfs

Request

  1. 通常 ROOT URLCONF 決定, 但若請求HttpRequest 物件存在 urlconf(被中介軟體新增)屬性,它的值會放在根urls配置
  2. 框架載入模組會在 urlpatterns 變數上查詢,它 django.urls.path() 或 django.urls.re_path()例項上的序列
  3. 框架依次找到了第一個匹配的 URL 正則,會立即終止,不會採用後續符合規則的路由
  4. 一旦匹配,Django 則匯入並呼叫給定的檢視,檢視接收以下引數
    • HttpRequest 例項
    • 傳遞關鍵參建將覆蓋在 django.urls.path() 或 django.urls.re_path()內的可選關鍵字
  5. 無匹配,將拋異常框架會回撥相應的錯誤控制程式碼檢視

Django中的 urlconf 更類似於其他框架中的路由器, ROOT_URLCONF --> urlpatterns

檢視

  • <int:question_id> 類似正則中的命名子模式概念,<int: 是一個轉換器,將匹配到路徑轉化為int型
#polls/views.py

def detail(request, question_id):
    return HttpResponse("You're looking at question %s." % question_id)

def results(request, question_id):
    response = "You're looking at the results of question %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("You're voting on question %s." % question_id)

#polls/urls.py
from django.urls import path

from . import views

urlpatterns = [
    # ex: /polls/
    path('', views.index, name='index'),
    # ex: /polls/5/
    path('<int:question_id>/', views.detail, name='detail'),
    # ex: /polls/5/results/
    path('<int:question_id>/results/', views.results, name='results'),
    # ex: /polls/5/vote/
    path('<int:question_id>/vote/', views.vote, name='vote'),
]
  • 每個 view 對請求響應 HttpResponse 物件,或者諸如 Http404 這樣的異常
  • 專案 TEMPLATES 配置,框架優先從 INSTALLED_APPS 下的預設 tempaltes 子目錄尋找

快捷函式

  • django.shortcuts: render()
    • 隱式使用了模板載入器
    • 包裝返回一個 HttpResponse 物件
    • 不再顯式的匯入 loader 和 HttpResponse
    • 原型 def render(request, template_name, context=None, content_type=None, status=None, using=None)
  • django.shortcuts:get_object_or_404()
from django.http import Http404
from django.shortcuts import render

from .models import Question
# ...
def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})

將模型的 get() 與 Http404合二為一, 下面的程式碼與上述等價

from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})
  • get_list_or_404() 亦類似

模板系統

  • 屬性訪問使用 . 語法, 輸出 {{ }}
  • 方法呼叫通常使用表示式模板標誌如 {% for %}
  • 移除模板中的 URL 硬編碼,使用 {% url %} 實際指向 polls.urls 模組
  # 硬編碼
  <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

  # 動態url, 引數detail引用自配置 path()中的name,相當於命名路由
  <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

命名url

  • 框架通過在應用的 URLconf 配置中,增加 app_name 設定名稱空間,以其區分在不同應用中的相同 url 命名
  • 帶有應用名稱空間 url 名稱,在模板中的應用如下
  # polls/templates/polls/index.html¶
  <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

進入 Part 4 學習

原始碼

第一個Django應用程式

相關文章