为了增加程序的友好和健壮性,修改view代码,处理以下如果出现404,页面的UI展示。
修改view代码
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的报错,页面会提示“Question does not exist”,否则,跳转到detail.html页面
编辑detail.html如下:
{{ question }}
这里django还有一种便捷的处理404的办法,编辑views如下
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})
优化detail.html页面代码,引入choice的选项内容
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
我们在question的模板中,写入的语句如下,
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
其中对于父链接 /polls/的引用,是写死的,如果polls某一天修改为/pollsAndVote,我们就需要跑去修改对应的模板,产生了很多工作量。这里降耦合,将html的url的部分,改为引用。
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
以上代码的{%url 'detail' question.id%},是从urlConf里面,读取detail的url(即配置当中的 /polls/+'<int:question_id>',后面的question_id将数值传入int),之前urlConf是这么配置的:
# the 'name' value as called by the {% url %} template tag
path('<int:question_id>/', views.detail, name='detail'),
通过以上操作,如果我们修改detail的链接,就不需要同时修改urlConf和对应模板的html,而只需要修改urlConf。
比如您想将polls detail view的URL更改为其他内容,比如polls/specifics/12/,只需要修改p
olls/urls.py
:
...
# added the word 'specifics'
path('specifics/<int:question_id>/', views.detail, name='detail'),
...
在detail.html中,我们调用的是polls的url中的“detail"这个名字的url,实际项目中,可能有其他的叫blog的url也有一个detail这个名字。为了将模板和app对应起来,可以通过命名 app_name来一一对应
这个地方不知道解释得对不对,没有做过复杂得项目,不太理解为什么要用这个,原文如下:
The tutorial project has just one app, polls.
In real Django projects, there might be five, ten, twenty apps or more.
How does Django differentiate the URL names between them?
For example, the polls app has a detail view, and so might an app on the same project that is for a blog.
How does one make it so that Django knows which app view to create for a url when using the {% url %} template tag?
然后就提出了使用app_name的解决方案。
from django.urls import path
from . import views
app_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'),
]
更改detail.html
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
最近在写django的网页代码,刚好用到这里。
优化前的框架: 编辑mysite的urls,将polls的各个views加进去,如果polls里面叫views,那新建一个product的app,里面的views就要改名;如果polls里面的有好几个页面都叫 manage.html,那就要给各种html加前缀,这里可以通过给templates里面增加文件夹解决。