django入門-檢視-part3

曲珂發表於2017-03-06

尊重作者的勞動,轉載請註明作者及原文地址 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>

看到區別了嗎

 

好了 本節完

 

相關文章