写一个真正有用的视图
每个视图必须要做的只有两件事:
返回一个包含被请求页面内容的HttpResponse对象,或抛出一个异常,比如Http404。
至于你还想干些什么,随便你。
你的视图可以从数据库里读取记录,可以使用一个模板引擎(比如django自带的,或者其他第三方的),可以生成一个PDF文件,可以输出一个XML,创建一个ZIP文件,你可以做任何你想做的事,使用任何你想用的python库。
django只要求返回的是一个HttpResponse,或者抛出一个异常
因为django自带的数据库API很方便,我们在前面学过,所以我们试试在视图里使用它。
在index()函数里插入一些新的内容,让它能展示数据库里以发布日期排序的最近5个投票问题,以空格分割:
from django.shortcuts import render # Create your views here. 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)
其他视图函数不变(detail,results,vote)
为了演示,我们添加6个问题:
查看数据库中的数据
浏览器访问http://127.0.0.1:8000/polls/,触发index视图函数:
这里有个问题:页面的设计写死在视图函数的代码里的。如果你想改变页面的样子,你需要编辑python代吗。所以让我们使用django的模板系统,只要创建一个视图,就可以将页面的设计从代码中分离出来。
使用django的模板系统
首先,在你的polls项目里创建一个templates目录。django将会在这个目录里查找模板文件。
你的项目的TEMPLATES配置项描述了django如何载入和渲染模板。默认的设置文件设置了DjangoTemplates后端,并将APP_DIRS设置成了True。这一选项将会让DjangoTemplates在每个INSTALLED_APPS文件夹中寻找”templates”子目录。
settings.py:
INSTALLED_APPS = [ 'polls.apps.PollsConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
在你刚刚创建的templates目录里,再创建一个目录polls,然后在其中新建一个文件index.html。换句话说,你的模板文件的路径应该是polls/templates/polls/index.html。因为django会寻找到对应的app_directories(不太理解),所以你只需要使用polls/index.html就可以引用到这一模板了。
模板命名空间
虽然我们现在可以将模板文件直接在polls/templates文件中(而不是再建立一个polls子文件夹),但是这样做不太好。django将会选择第一个匹配的模板文件,如果你有一个模板文件正好和另一个应用中的某个模板文件重名,django没有办法区分它们。我们需要帮助django选择正确的模板,最简单的方法就是把它们放入个字的命名空间中,也就是把这些模板放入一个和自身应用重名的子文件夹里。
所以我们在templates文件夹下,新建一个跟应用重名的文件夹”polls”,然后在该子文件夹下新建一个index.html文件:polls/templates/polls/index.hmtl
在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 %}
然后,让我们更新一下polls/views.py里的index视图来使用模板:
视图函数中使用模板:
polls/view.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))
上下文:
上述代码的作用是,载入polls/index.html模板文件,并且向它传递一个上下文(context)。这个上下文是一个字典,它将模板内的变量映射为python对象。
此处context是一个字典,渲染模板时通过template.render()方法把context和请求对象传入到模板文件中,在模板文件中,对context中的对象进行渲染
再次触发视图函数,渲染模板
浏览器访问”polls/”,将会看到一个无序列表,列出了我们在之前添加的投票问题,链接指向了这个投票的详情页。
点击链接: