設計哲學
在Django中一個檢視有指定函式和指定模版組成。
對於某些特定的應用應該分成若干檢視。例如部落格系統
- Blog主頁面
- 詳細頁面入口
- 基於年的頁面展示
- 基於月的頁面展示
- 基於天的頁面展示
- 評論行為(action)
而對於投票應用,則由
- 投票主頁
- 投票細節頁面
- 投票結果頁面
- 投票行為(action)
在Django中,頁面由檢視(views)表達,而檢視由一個簡單的函式(成員函式)展示。Django通過URL來精確匹配一個檢視,即URLconfs
檢視層的編寫
1. 編寫應用試圖polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll index.")
2. 編寫應用URLpolls/urls.py
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index')
)
3. 編寫專案URL
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
URL的引數
- 第一個引數為正規表示式,用r開頭的原始字串不會被Python轉義
- 第二個引數指定檢視函式
- 第三個引數,一般不用
- 第四個引數為此URL取別名
通過URL傳遞引數
1. 編寫URL
(?P<poll_id>\d+)
指該部分的URL為一個引數,引數的名字由?P<poll_id>指定,\d+只由一個或更多的陣列組成。
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
2. 接收引數
def detail(request, poll_id):
return HttpResponse("You're looking at poll %s." % poll_id)
def results(request, poll_id):
return HttpResponse("You're looking at the results of poll %s." % poll_id)
def vote(request, poll_id):
return HttpResponse("You're voting on poll %s." % poll_id)
與資料庫連線,顯示其內容
1. 編寫檢視函式
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
output = ', '.join([p.question for p in latest_poll_list])
return HttpResponse(output)
2. 建立模版
這裡推薦模版的位置是polls/templates/polls/index.html
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
3. 修改檢視函式
from django.http import HttpResponse
from django.template import RequestContext, loader
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_poll_list': latest_poll_list,
})
return HttpResponse(template.render(context))
4. 利用快捷方式簡化程式碼
from django.shortcuts import render
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
context = {'latest_poll_list': latest_poll_list}
return render(request, 'polls/index.html', context)
查詢頁面——404頁面的返回
利用try-catch解決404
from django.http import Http404
from django.shortcuts import render
from polls.models import Poll
# ...
def detail(request, poll_id):
try:
poll = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise Http404
return render(request, 'polls/detail.html', {'poll': poll})
此時的polls/detail.html可只填寫內容{{poll}}
利用快捷方式簡化程式碼
from django.shortcuts import render, get_object_or_404
from polls.models import Poll
# ...
def detail(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
return render(request, 'polls/detail.html', {'poll': poll})
針對get的函式為get_object_or_404,針對filter的函式為get_list_or_404。
此快捷方式有助於在檢視層不用關心資料層的內容,更好的解耦合。
使用模版系統
#polls/detail.html
<h1>{{ poll.question }}</h1>
<ul>
{% for choice in poll.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
poll.choice_set.all為函式呼叫,返回一個列表。
URL別名的使用
1. 為了簡化URL,消除掉難看的程式碼。
<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
<li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
#既是前面提到的URL別名
2. URL名稱空間
上文所述的別名會造成重名而使Django匹配出錯,因此使用名稱空間
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
)
相應地,修改
<li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>