Django4.0 寫一個(gè)真正有用的視圖

2022-03-12 11:20 更新

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

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

Django 只要求返回的是一個(gè) ?HttpResponse ?,或者拋出一個(gè)異常。

因?yàn)?Django 自帶的數(shù)據(jù)庫(kù) API 很方便,我們?cè)囋囋谝晥D里使用它。我們?cè)?index() 函數(shù)里插入了一些新內(nèi)容,讓它能展示數(shù)據(jù)庫(kù)里以發(fā)布日期排序的最近 5 個(gè)投票問題,以空格分割:

from django.http import HttpResponse

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    output = ', '.join([q.question_text for q in latest_question_list])
    return HttpResponse(output)

# Leave the rest of the views (detail, results, vote) unchanged

這里有個(gè)問題:頁(yè)面的設(shè)計(jì)寫死在視圖函數(shù)的代碼里的。如果你想改變頁(yè)面的樣子,你需要編輯 Python 代碼。所以讓我們使用 Django 的模板系統(tǒng),只要?jiǎng)?chuàng)建一個(gè)視圖,就可以將頁(yè)面的設(shè)計(jì)從代碼中分離出來(lái)。

首先,在你的 ?polls目錄里創(chuàng)建一個(gè) ?templates ?目錄。Django 將會(huì)在這個(gè)目錄里查找模板文件。

你項(xiàng)目的 ?TEMPLATES ?配置項(xiàng)描述了 Django 如何載入和渲染模板。默認(rèn)的設(shè)置文件設(shè)置了 ?DjangoTemplates后端,并將 ?APP_DIRS設(shè)置成了 True。這一選項(xiàng)將會(huì)讓 ?DjangoTemplates在每個(gè) ?INSTALLED_APPS文件夾中尋找 "templates" 子目錄。這就是為什么盡管我們沒有像在第二部分中那樣修改 DIRS 設(shè)置,Django 也能正確找到 polls 的模板位置的原因。

在你剛剛創(chuàng)建的 ?templates ?目錄里,再創(chuàng)建一個(gè)目錄 ?polls?,然后在其中新建一個(gè)文件 ?index.html? 。換句話說(shuō),你的模板文件的路徑應(yīng)該是 ?polls/templates/polls/index.html? 。因?yàn)閌`app_directories`` 模板加載器是通過(guò)上述描述的方法運(yùn)行的,所以 Django 可以引用到 ?polls/index.html? 這一模板了。

注意:

雖然我們現(xiàn)在可以將模板文件直接放在 ?polls/templates? 文件夾中(而不是再建立一個(gè) polls 子文件夾),但是這樣做不太好。Django 將會(huì)選擇第一個(gè)匹配的模板文件,如果你有一個(gè)模板文件正好和另一個(gè)應(yīng)用中的某個(gè)模板文件重名,Django 沒有辦法區(qū)分它們。我們需要幫助 Django 選擇正確的模板,最好的方法就是把他們放入各自的 命名空間 中,也就是把這些模板放入一個(gè)和 自身 應(yīng)用重名的子文件夾里。

將下面的代碼輸入到剛剛創(chuàng)建的模板文件中:

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

然后,讓我們更新一下 ?polls/views.py? 里的 ?index視圖來(lái)使用模板:

from django.http import HttpResponse
from django.template import loader

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)