写更多视图
现在让我们再添加一些视图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通过添加以下path()调用将这些新视图连接到模块中 :
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
写出实际做某事的视图
一个新index() 视图,它根据发布日期显示系统中最新的5个轮询问题,以逗号分隔:
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)
但是这里存在一个问题:页面的设计在视图中是硬编码的。如果要更改页面的外观,则必须编辑此Python代码。因此,让我们使用Django的模板系统,通过创建视图可以使用的模板将设计与Python分离。
首先,创建目录中调用templates的polls目录。Django会在那里寻找模板。
将以下代码放在新建的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 %}
现在让我们更新我们的index视图polls/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))
快捷方式 render()
加载模板,填充上下文并返回HttpResponse带有渲染模板结果的对象是一种非常常见的习惯用法 。Django提供了一个捷径。这是完整的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})
这里的新概念:Http404如果不存在具有请求ID的问题,则视图会引发异常。
稍后我们将讨论您可以在该polls/detail.html模板中添加的内容,但是如果您希望快速获得上述示例,则只需包含以下内容的文件:
{{ question }}
快捷方式 get_object_or_404()
如果对象不存在,使用get() 和提升这是一个非常常见的习惯用法Http404。Django提供了一个捷径。这是detail()视图,重写:
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_object_or_404()函数将Django模型作为其第一个参数和任意数量的关键字参数,并将其传递给get()模型管理器的函数。Http404如果对象不存在则引发。
使用一个模板
返回detail()我们的民意调查应用程序的视图。给定上下文变量question,这是polls/detail.html模板的外观:
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
删除模板中的硬编码
请记住,当我们在polls/index.html 模板中写入问题的链接时,链接部分硬编码如下:
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
这种硬编码,紧密耦合方法的问题在于,在具有大量模板的项目上更改URL变得具有挑战性。但是,由于您path()在polls.urls模块中的函数中定义了name参数,因此可以使用模板标记来消除对URL配置中定义的特定URL路径的依赖:
- {{ question.question_text }}
这种方式的工作方式是查找polls.urls模块中指定的URL定义 。您可以在下面确切地看到“详细信息”的URL名称的位置:
the 'name' value as called by the {% url %} template tag path('<int:question_id>/', views.detail, name='detail'),
如果您想将民意调查详细信息视图的URL更改为其他内容,可能polls/specifics/12/会更改为在模板(或模板)中执行此操作,您可以将其更改为polls/urls.py:
added the word 'specifics' path('specifics/<int:question_id>/', views.detail, name='detail'),
命名url名称
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'), ]
现在更改您的polls/index.html模板:
指向命名空间详细信息视图:
民调/模板/调查/ index.html的¶
未完待续…