Django4.0 寫一個真正有用的視圖

2022-03-12 11:20 更新

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

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

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

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

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

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

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

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

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

注意:

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

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)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號