尊重作者的勞動,轉載請註明作者及原文地址 http://www.cnblogs.com/txwsqk/p/6511384.html
完全翻譯自官方文件 https://docs.djangoproject.com/en/1.10/intro/tutorial03/
本節講檢視
我們設計一個簡單投票頁面,它有如下3個功能
1. 顯示要投票的問題
2. 點選"投票"按鈕提交你的選項
3. 展示這個投票的結果
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.conf.urls import url from . import views urlpatterns = [ # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
一個檢視只會返回 HttpResponse 或 Http404
下面寫一個從資料庫獲取內容的view
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)
我們在程式碼裡硬編碼了頁面只返回5條內容,這很外行,所以我們用django的模板系統
django預設會在這個目錄結構下讀取我們的模板檔案
polls/templates/polls/index.html
就是在你的應用目錄下建立資料夾 templates ,再在templates裡建立一個跟應用名字一樣的目錄poolls
這個index.html的訪問路徑就是 polls/index.html
你的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 %}
相應的修改你的views.py
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))
context 就是一個字典, 模板裡會使用這個變數
上面的方法稍顯麻煩,先載入loader模板檔案,再渲染render檔案,django為我們提供了一個更方面的命令 render()
繼續修改我們的使用,我們使用render重寫上面的index()
from django.shortcuts import render from .models import Question 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)
當訪問的頁面不存在時,我們拋一個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})
再精簡程式碼,正常獲取和拋404可以用一個方法 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})
類似的還有get_list_or_404(),還有最好用filter()函式代替get(),因為get()會拋一個Http404異常
模板系統開講
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>
用點來訪問變數的屬性
來看這段程式碼,我們在href中硬編碼了訪問路徑
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
怎麼解決呢,在url()方法里加name引數
... # the 'name' value as called by the {% url %} template tag url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), ...
修改以後,上面的硬編碼變成這樣
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
這樣即使你修改了你的url路徑,那麼你的html也不需要修改.
URL名稱空間
在一個django專案裡可能包含很多應用, 那麼就會出現多個url(name="這裡的名字有重複"),那麼怎麼解決呢
from django.conf.urls import url from . import views app_name = 'polls' # <==就是它 urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ]
同時修改你的html
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
看到區別了嗎
好了 本節完