91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Django項目怎么實現視圖和模板

發布時間:2020-08-25 11:00:00 來源:億速云 閱讀:150 作者:Leah 欄目:編程語言

Django項目怎么實現視圖和模板?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

一、概述

一個視圖就是一個頁面,通常提供特定的功能,使用特定的模板。例如:在一個博客應用中,你可能會看到下列視圖:

博客主頁:顯示最新發布的一些內容每篇博客的詳細頁面:博客的永久鏈接基于年的博客頁面:顯示指定年內的所有博客文章基于月的博客頁面:顯示指定月內的所有博客文章基于天的博客頁面:顯示指定日內的所有博客文章發布評論:處理針對某篇博客發布的評論

在我們的投票應用中,我們將建立下面的視圖:

問卷“index”頁:顯示最新的一些問卷問卷“detail”頁面:顯示一個問卷的詳細文本內容,沒有調查結果但是有一個投票或調查表單。問卷“results”頁面:顯示某個問卷的投票或調查結果。投票動作頁面:處理針對某個問卷的某個選項的投票動作。

在Django中,網頁和其它的一些內容都是通過視圖來處理的。視圖其實就是一個簡單的Python函數(在基于類的視圖中稱為方法)。Django通過對比請求的URL地址來選擇對應的視圖。

在你上網的過程中,很可能看見過像這樣的 URL: "ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B" 。別擔心,Django 里的 URL規則要比這優雅的多!

一個 URL 模式定義了一種 URL 的基本格式,比如:/newsarchive/<year>/<month>/。

為了將 URL 和視圖關聯起來,Django 使用了 'URLconfs' 來配置。URLconf 將 URL 模式映射到視圖。

二、編寫視圖

下面,打開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文件中加入下面的url模式,將其映射到我們上面新增的視圖。

from django.urls import pathfrom . import viewsurlpatterns = [
    # 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'),]

現在去瀏覽器中訪問/polls/34/(注意:這里省略了域名。另外,使用了二級路由后,url中都要添加字符串polls前綴,參考前面的章節),它將調用detail()函數,然后在頁面中顯示你在url里提供的ID。訪問/polls/34/results/和/polls/34/vote/,將分別顯示預定義的偽結果和投票頁面。(PS:這里就不貼圖了,請大家務必自己動手測試,多實踐。)

上面訪問的路由過程如下:當有人訪問/polls/34/地址時,Django將首先加載mysite.urls模塊,因為它是settings文件里設置的根URL配置文件。在該文件里,Django發現了urlpatterns變量,于是在其內按順序進行匹配。當它匹配上了polls/,就裁去url中匹配的文本polls/,然后將剩下的文本“34/”,傳遞給polls.urls進行下一步的處理。在polls.urls中,又匹配到了<int:question_id>/,最終結果就是調用該模式對應的detail()視圖,也就是下面的函數:

detail(request=<HttpRequest object>, question_id=34)

函數中的question_id=’34’參數,是由<int:question_id>/而來。使用尖括號“捕獲”這部分 URL,且以關鍵字參數的形式發送給視圖函數。上述字符串的question_id部分定義了將被用于區分匹配模式的變量名,而int則是一個轉換器決定了應該以什么變量類型匹配這部分的 URL 路徑。

沒必要書寫一個如下的較為愚蠢的包含.html的模式,它顯然是沒必要,不夠簡練的:

path('polls/latest.html', views.index),

三、編寫能實際干點活的視圖

每個視圖至少做兩件事之一:返回一個包含請求頁面的HttpResponse對象或者彈出一個類似Http404的異常。其它的則隨你便,你愛干嘛干嘛。

下面是一個新的index()視圖,用于替代先前無用的index,它會根據發布日期顯示最近的5個投票問卷。

from django.http import HttpResponsefrom .models import Questiondef 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
    # 省略了那些沒改動過的視圖(detail, results, vote)

這里有個非常重要的問題:在當前視圖中的HTML頁面是硬編碼的。如果你想改變頁面的顯示內容,就必須修改這里的Python代碼。為了解決這個問題,需要使用Django提供的模板系統,解耦視圖和模板之間的硬連接。

首先,在polls目錄下創建一個新的templates目錄,Django會在它里面查找模板文件。

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

在templates目錄中,再創建一個新的子目錄名叫polls,進入該子目錄,創建一個新的html文件index.html。換句話說,你的模板文件應該是polls/templates/polls/index.html。因為 Django 會尋找到對應的app_directories ,所以你只需要使用polls/index.html就可以引用到這一模板了。

模板命名空間:

你也許會想,為什么不把模板文件直接放在polls/templates目錄下,而是費勁的再建個子目錄polls呢?設想這么個情況,有另外一個app,它也有一個名叫index.html的文件,當Django在搜索模板時,有可能就找到它,然后退出搜索,這就命中了錯誤的目標,不是我們想要的結果。解決這個問題的最好辦法就是在templates目錄下再建立一個與app同名的子目錄,將自己所屬的模板都放到里面,從而達到獨立命名空間的作用,不會再出現引用錯誤。

現在,將下列代碼寫入文件polls/templates/polls/index.html:

{% 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.html文件生效:

from django.http import HttpResponse
from django.template import loader
from .models import Questiondef 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))

上面的代碼會加載polls/index.html文件,并傳遞給它一個參數。這個參數是一個字典,包含了模板變量名和Python對象之間的映射關系。

在瀏覽器中通過訪問/polls/,你可以看到一個列表,包含“What’s up”的問卷,以及連接到其對應詳細內容頁面的鏈接點。

注意:如果你顯示的是No polls are available.說明你前面沒有添加Questions對象。前面的大量手動API操作你沒有做。沒關系,我們在admin中追加對象就可以。

快捷方式:render()

在實際運用中,加載模板、傳遞參數,返回HttpResponse對象是一整套再常用不過的操作了,為了節省力氣,Django提供了一個快捷方式:render函數,一步到位!

修改成下面的代碼:

from django.shortcuts import render
from .models import Questiondef 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)

注意,我們不再需要導入 loader和 HttpResponse,而是從django.shortcuts導入了render。

render()函數的第一個位置參數是請求對象(就是view函數的第一個參數),第二個位置參數是模板。還可以有一個可選的第三參數,一個字典,包含需要傳遞給模板的數據。最后render函數返回一個經過字典數據渲染過的模板封裝而成的HttpResponse對象。

四、返回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})

這里有個新知識點,如果請求的問卷ID不存在,那么會彈出一個Http404錯誤。

如果你想試試上面這段代碼是否正常工作的話,你可以新建polls/detail.html文件,暫時寫入下面的代碼:

{{ question }}

快捷方式:get_object_or_404()

就像render函數一樣,Django同樣為你提供了一個偷懶的方式,替代上面的多行代碼,那就是get_object_or_404()方法,參考下面的代碼:

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

別說我沒提醒你,和render一樣,也需要從Django內置的快捷方式模塊中導出get_object_or_404()!

get_object_or_404()方法將一個Django模型作為第一個位置參數,后面可以跟上任意個數的關鍵字參數,如果對象不存在則彈出Http404錯誤。

同樣,還有一個get_list_or_404()方法,和上面的get_object_or_404()類似,只不過是用來替代filter()函數,當查詢列表為空時彈出404錯誤。(filter是模型API中用來過濾查詢結果的函數,它的結果是一個列表集。而get則是查詢一個結果的方法,和filter是一個和多個的區別!)

為什么我們使用輔助函數get_object_or_404()而不是自己捕獲ObjectDoesNotExist異常呢?還有,為什么模型 API 不直接拋出ObjectDoesNotExist而是拋出 Http404呢?因為這樣做會增加模型層和視圖層的耦合性。指導 Django 設計的最重要的思想之一就是要保證松散耦合。一些受控的耦合將會被包含在 django.shortcuts 模塊中。

五、 使用模板系統

回過頭去看看我們的 detail() 視圖。它向模板傳遞了上下文變量 question 。下面是 polls/detail.html 模板里正式的代碼:

<h2>{{ question.question_text }}</h2><ul>{% for choice in question.choice_set.all %}    
<li>{{ choice.choice_text }}</li>{% endfor %}</ul>

在模板系統中圓點.是萬能的魔法師,你可以用它訪問對象的屬性。在例子{{ question.question_text }}中,DJango首先會在question對象中嘗試查找一個字典,如果失敗,則嘗試查找屬性,如果再失敗,則嘗試作為列表的索引進行查詢。

在 {% for %}循環中的方法調用——question.choice_set.all其實就是Python的代碼question.choice_set.all(),它將返回一組可迭代的Choice對象,并用在{% for %}標簽中。

這里我們對Django模板語言有個簡單的印象就好,更深入的介紹放在后面。

六、刪除模板中硬編碼的URLs

在polls/index.html文件中,還有一部分硬編碼存在,也就是href里的“/polls/”部分:

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

它對于代碼修改非常不利。設想如果你在urls.py文件里修改了路由表達式,那么你所有的模板中對這個url的引用都需要修改,這是無法接受的!

我們前面給urls定義了一個name別名,可以用它來解決這個問題。具體代碼如下:

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
Django會在polls.urls文件中查找name='detail'的url,具體的就是下面這行:
path('<int:question_id>/', views.detail, name='detail'),

舉個栗子,如果你想將polls的detail視圖的URL更換為polls/specifics/12/,那么你不需要在模板中重新修改url地址了,僅僅只需要在polls/urls.py文件中,將對應的正則表達式改成下面這樣的就行了,所有模板中對它的引用都會自動修改成新的鏈接:

# 添加新的單詞'specifics'

path('specifics/<int:question_id>/', views.detail, name='detail'),

七、URL names的命名空間

本教程例子中,只有一個app也就是polls,但是在現實中很顯然會有5個、10個、更多的app同時存在一個項目中。Django是如何區分這些app之間的URL name呢?

答案是使用URLconf的命名空間。在polls/urls.py文件的開頭部分,添加一個app_name的變量來指定該應用的命名空間:

from django.urls import pathfrom . import viewsapp_name = 'polls'urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/results/', views.results, name='results'),
    path('<int:question_id>/vote/', views.vote, name='vote'),]

現在,讓我們將代碼修改得更嚴謹一點,將polls/templates/polls/index.html中的

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

修改為:

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

關于Django項目怎么實現視圖和模板問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德昌县| 临安市| 泰来县| 闽清县| 宜君县| 定南县| 华安县| 林州市| 哈密市| 定州市| 康保县| 红桥区| 隆回县| 南康市| 徐州市| 玉山县| 会昌县| 本溪| 元谋县| 郴州市| 绥宁县| 广饶县| 龙井市| 平南县| 泉州市| 通渭县| 宁国市| 鲁甸县| 高碑店市| 布尔津县| 米易县| 临汾市| 商水县| 延川县| 临江市| 京山县| 罗甸县| 庄浪县| 寿宁县| 和林格尔县| 普陀区|