Django 視圖與模板的使用

了解前提:Django請求和響應設置
參考

在前提的演示中, HTML被直接硬編碼在 Python 代碼之中的用法只是為了方便演示。

但是實際生產(chǎn)中, 將頁面的設計和Python的代碼分離開會更干凈簡潔更容易維護。 我們可以使用 Django的 模板系統(tǒng) (Template System)來實現(xiàn)這種模式
—————————————————————————————————————

視圖

每個視圖必須要做的只有兩件事:返回一個包含被請求頁面內(nèi)容的 HttpResponse 對象,或者拋出一個異常,比如 Http404 。

視圖可以從數(shù)據(jù)庫里讀取記錄,可以使用一個模板引擎(比如 Django 自帶的,或者其他第三方的),可以生成一個 PDF 文件,可以輸出一個 XML,創(chuàng)建一個 ZIP 文件,你可以做任何你想做的事,使用任何你想用的 Python 庫。

—————————————————————————————————————

模板系統(tǒng)基本知識

項目的 TEMPLATES 配置項描述了 Django 如何載入和渲染模板。默認的設置文件設置了 DjangoTemplates 后端,并將 APP_DIRS 設置成了 True。這一選項將會讓 DjangoTemplates 在每個 INSTALLED_APPS 文件夾中尋找 "templates" 子目錄。

模板文件的路徑應該是 : [應用根目錄]/templates/[應用名]/[模板名].html

因為 Django 會尋找到對應的 app_directories ,所以你只需要使用 [應用名]/[模板名].html 就可以引用到這一模板了

一、模本概念和組成

模板是一個文本,用于分離文檔的表現(xiàn)形式和內(nèi)容。 模板定義了占位符以及各種用于規(guī)范文檔該如何顯示的各部分基本邏輯(模板標簽)。 模板通常用于產(chǎn)生HTML,但是Django的模板也能產(chǎn)生任何基于文本格式的文檔。

示例:

<html>
<head><title>Ordering notice</title></head>

<body>

<h1>Ordering notice</h1>

<p>Dear {{ person_name }},</p>

<p>Thanks for placing an order from {{ company }}. It's scheduled to
ship on {{ ship_date|date:"F j, Y" }}.</p>

<p>Here are the items you've ordered:</p>

<ul>
{% for item in item_list %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

{% if ordered_warranty %}
    <p>Your warranty information will be included in the packaging.</p>
{% else %}
    <p>You didn't order a warranty, so you're on your own when
    the products inevitably stop working.</p>
{% endif %}

<p>Sincerely,<br />{{ company }}</p>

</body>
</html>
其中的格式含義

模板變量 :
用兩個大括號括起來的文字, 意味著在此處插入指定變量的值。
附:模板變量的解析順序
模板標簽 :
被大括號和百分號包圍的文本(例如 {% if ordered_warranty %} )是 模板標簽(template tag) 。標簽(tag)定義比較明確,即: 僅通知模板系統(tǒng)完成某些工作的標簽。

過濾器:
形如例子中: {{ship_date|date:”F j, Y” }}格式作為過濾器(filter), 我們將變量ship_date傳遞給date過濾器,同時指定參數(shù)”F j,Y”。date過濾器根據(jù)參數(shù)進行格式輸出。 過濾器是用管道符(|)來調(diào)用的。

二、模板結(jié)合視圖的使用

如果要額外了解模板作為python庫的獨立運行機制, 還有其中內(nèi)置標簽和模板的特殊行為,
參考: 模板系統(tǒng)獨立工作原理總結(jié)

由于目前普遍都是模本結(jié)合視圖一起呈現(xiàn), 以下主要總結(jié)結(jié)合使用的方法。

1、首先創(chuàng)建模板結(jié)構(gòu) [應用根目錄]/templates/[應用名]/[模板名].html

2、完善模板內(nèi)容, 設計模板交互規(guī)則

3、創(chuàng)建模板對應視圖, 將視圖的請求訪問注冊到urls.py文件

4、在視圖中使用template 庫的get_template獲取模板對象, 使用shortcuts 或template 庫的render渲染模板(基礎用法), 將復雜的數(shù)據(jù)或數(shù)據(jù)對象以字典的形式傳遞給模本系統(tǒng), 由后者進行深度變量的查找。

用例參考

三、在模板中使用Http404方法拋出404, 以便django處理并顯示404頁面

使用情景, 當數(shù)據(jù)庫根據(jù)頁面交互數(shù)據(jù)查不到數(shù)據(jù), 需要手動扔出404, 但路由配置失敗或者訪問到錯誤路由是, django自動報404,

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})

上面這個流程主要是當數(shù)據(jù)庫根據(jù)頁面交互數(shù)據(jù)查不到數(shù)據(jù), 需要手動扔出404, 其實有一個快捷函數(shù)可以直接兩步操作一起進行get_object_or_404。

4、去除模板訪問的硬編碼

由于在模板中定義到api的訪問路由由urls.py文件定義, 而后者隨時可能會改變一節(jié)路由, 故路由在模板中不能進行硬編碼。
形如:

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
// polls是路由匹配字符

需要改成:

<li><a href="{% url 'GDweb:detail' question.id %}">{{ question.question_text }}</a></li>

其中GDweb:detail為命名空間為GDweb的urls.py文件中的參數(shù)name為detail的指定路由, 指定之后, 不管路由匹配規(guī)則怎么變, 路由名字不變就可精準匹配。
GDweb:detail代表命名空間為GDweb(對應應用)下的路由, 為了讓多應用下Django 知道{% url %}標簽到底對應哪一個應用的 URL,在urls.py文件中, 可以定義app_name變量指定命名空間。

—————————————————————————————————————

shortcuts 庫的一個快捷函數(shù): render()?

「載入模板,填充上下文,再返回由它生成的 HttpResponse 對象」是一個非常常用的操作流程。于是 Django 提供了一個快捷函數(shù),我們用它來重寫 index() 視圖:

def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)
基于數(shù)據(jù)庫查詢?yōu)榭?04拋出的快捷函數(shù): get_object_or_404()?

嘗試用 模型的get() 函數(shù)獲取一個對象,如果不存在就拋出 Http404 錯誤也是一個普遍的流程。Django 也提供了一個快捷函數(shù),下面是修改后的詳情 detail() 視圖代碼:

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})

—————————————————————————————————————

模板系統(tǒng)所有內(nèi)置的tags和filters詳細

Django 模板含有很多內(nèi)置的tags和filters

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容