在demo/views.py中添加这些代码:
def detail(request, question_id):
returnHttpResponse("You're looking at question %s."% question_id)
def results(request, question_id):
response ="You're looking at the results of question %s."
returnHttpResponse(response % question_id)
def vote(request, question_id):
returnHttpResponse("You're voting on question %s."% question_id)
在demo/urls.py中加入如下代码,对应url的访问规则:
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'),
]
为了让request做点什么事情,在demo/views.py中添加这些代码:
from django.http importHttpResponse
from.models importQuestion
def index(request):
latest_question_list =Question.objects.order_by('-pub_date')[:5]
output =', '.join([q.question_text for q in latest_question_list])
returnHttpResponse(output)
为了不让view层的代码hard-code,我们使用django的template功能,在demo下创建一个名为templates的文件夹
在其下polls/templates/polls/index.html放入代码:
{%if latest_question_list %}
<ul>
{%for question in latest_question_list %}
<li><a href="/demo/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{%else%}
<p>No polls are available.</p>
{% endif %}
在demo/views.py中也要修改,可以获得template的内容:
from django.http importHttpResponse
from django.template import loader
from.models importQuestion
def index(request):
latest_question_list =Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('demo/index.html')
context ={
'latest_question_list': latest_question_list,
}
returnHttpResponse(template.render(context, request))
启动服务后,可以看到页面是这样的:
然后我们再来重写一些demo/views.py的方法:
from django.shortcuts import render
from.models importQuestion
def index(request):
latest_question_list =Question.objects.order_by('-pub_date')[:5]
context ={'latest_question_list': latest_question_list}
return render(request,'demo/index.html', context)
在新的重写里面,我们不需要引入loader和HttpResponse,用render方法替换之。
当url链接中的id不存在的时候,启动404错误,就会给出提示,那么如何启动404错误呢?
首先,在demo/views.py中加入如下代码:
from django.http importHttp404
from django.shortcuts import render
from.models importQuestion
# ...
def detail(request, question_id):
try:
question =Question.objects.get(pk=question_id)
exceptQuestion.DoesNotExist:
raiseHttp404("Question does not exist")
return render(request,'demo/detail.html',{'question': question})
当然也要在demo/templates/demo/detail.html创建如下代码
还有一个比较快捷的办法是使用get_object_or_404()这个方法
把这段代码放入demo/views.py中
from django.shortcuts import get_object_or_404, render
from.models importQuestion
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request,'demo/detail.html',{'question': question})
除了get_object_or_404()外,还有get_list_or_404() 方法,也有类似的用途
使用template system:
在demo/templates/demo/detail.html中添加以下代码:
<h1>{{ question.question_text }}</h1>
<ul>
{%for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
可以看到在question中多了choice中的内容
关于URL中的hardcode如何移去:
我们看到在demo/index.html中的代码长这个样子
<li><a href="/demo/{{ question.id }}/">{{ question.question_text }}</a></li>
这个‘demo’实在是太难看了,我们要想办法移去,替换成:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
在demo/urls中可以看到如下代码:
...
# the 'name' value as called by the {% url %} template tag
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
...
不过我们希望在链接中加入“specifics”,这样可以更好地说明这是显示的是它的detail,那么就改成:
...
# added the word 'specifics'
url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
...
在URL中添加名字空间,避免不同的app的url冲突:
在demo/urls.py下面添加app_name:
from django.conf.urls import url
from.import views
app_name ='demo'
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'),
]
然后把demo/index.html中的如下代码:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
改为:
<li><a href="{% url 'demo:detail' question.id %}">{{ question.question_text }}</a></li>
这样在template中调用url的时候就不会发生命名冲突了