在Django中,web页面和其他内容由视图交付。
从URL到视图,Django用了所谓的URLconfs.URLconfs将URL模式映射到视图。
Writing more views
在polls/views.py中添加视图:
通过调用path(),连接这些视图到polls.urls.
Writing views that actually do something
每个视图负责做两件事中的一件:返回一个包含请求页面内容的HttpResponse对象,或者引发一个异常,比如Http404
视图可以从数据库中读取记录,也可以不读取。它可以使用Django之类的模版系统,也可以使用第三方Python模版系统。它可以生成PDF文件,输出XML,动态创建ZIP文件,任何你想要的文件,使用你想使用的Python库。
但在这里有一个问题:页面的设计在视图中是硬编码的,如果想要改变页面的外观,必须编辑Python代码。因此,使用Django模版系统,通过创建视图可以使用的模版,将设计与Python分离开来。
在Polls目录下创建templates目录。Django将会在这里寻找模版。
TEMPLATES 设置描述了Django如何加载和渲染模版。默认的配置文件配置了一个Django Templates后端,其APP_DIRS选项设置为True.按照约定,Django Templates查找INSTALLED_APPS中的每个“templates"子目录。
在templates目录下创建另一个目录polls.在polls中创建文件index.html.也就是说模版应为polls/templates/polls/index.html.
现在在polls/views.py中使用模版更新索引视图。
该代码加载了polls/index的模版,并传递给它一个上下文。上下文是一个字典,映射了模版变量名到Python对象。
A shortcut: render()
加载模版是一种非常常见的习惯用法。填满一个上下文和返回HttpResponse对象的结果呈现模版。下面是重写后的完整index()视图:
rende()函数将请求对象作为第一个参数,模版名作为第二个参数,字典作为第三个可选参数,它返回使用给定上下文呈现的给定模版的HttpResponse对象。
Raising a 404 error
当查找的问题id不存在时,视图引发Http404异常。
先在polls/detail.html下写以下内容:
A shortcut:get_object_or_404()
如果对象不存在,使用get()和Http404是非常常见的习惯用法,Django提供了一个捷径,下面是detail()视图,重写如下:
get_object_or_404()函数把Django model作为第一个参数,并把任意数量的的关键字参数传递给get函数的model管理器。如果对象不存在,就会引发Http404。
还有一个函数get_list_or_404(),和get_object_or_404()的作用相同,除了使用filter()替代get().如果list为空,引发Http404.
Use the template system
回到detail()视图中,给定上下文变量question
模版系统使用点查找语法来访问变量属性。在{{question.question_text}}中,首先Django对对象Question进行字典查找。如果做不到这一点,它会尝试属性查找,在本例中,这个是可行的。如果属性查找失败,它将尝试列表索引查找。
方法调用发生在{% for %}循环中。question.choice_set.all()返回Choice对象的迭代,适合在{% for %}标记中使用。
Removing hardcoded URLs in templates
这种硬编码,紧密耦合的方法的问题是:在具有大量模版的项目中更改URL非常困难,由于在poll.urls的path()函数中定义了name参数,可以通过使用{% URL %}模版标记来消除对URL配置中定义的特定URL路径的依赖。
这种方法的工作方式是在查找polls.urls中指定的URL定义。可以看看在detail中URL是如何定义的。
如果想改变poll detail view中的URL为其他东西,比如polls/specifics/12.可以在polls/urls.py中修改而不在template中修改。
Namespacing URL names
在这个工程中,只有一个应用程序poll.在Django项目中,可能有5个,10个,20个或更多的应用程序。Django如何区分它们之间的URL名称?比如poll应用有一个detail视图,可能在同一个工程下它是用于blog.如何使Django知道在使用{% url %}模版标记时为url创建那个应用程序视图?
做法就是在URLconf中加名称空间。在polls/urls.py中,直接添加app的名称来设置应用名称空间。
现在把polls/index.html模版从
改为指向名称空间的detai视图。