【Django 笔记】Django快速入门 第3节: 视图和模板
笔记基于官方文档和技术博客,从中提取关键信息,和记录笔记,例程详见官方文档。
完整官方文档:Django documentation
博客推荐:Django2.2教程
Django快速入门官方文档:Part 3: Views and templates
目录
1.视图
Django 中的视图的概念是「一类具有相同功能和模板的网页的集合」,一个视图就是一个页面,通常提供特定的功能,使用特定的模板。
在Django中,网页和其它的一些内容都是通过视图来处理的。视图其实就是一个简单的Python函数(在基于类的视图中称为方法)。Django通过对比请求的URL地址来选择对应的视图。
对于django的设计框架MVT,用户在URL中请求的是视图,视图接收请求后进行处理,并将处理的结果返回给请求者。
为了将 URL 和视图关联起来,Django 使用了 'URLconfs' 来配置。URLconf 将 URL 模式映射到视图。
(URLconf 的更多内容参考: URL调度器)
使用视图时需要进行两步操作:
- 定义视图函数
- 配置URLconf(进行路由配置)
1.1. 定义视图
- 视图就是一个Python函数,被定义在views.py中。
- 视图必须有一个参数,一般叫request,视图必须返回HttpResponse对象,HttpResponse中的参数内容会显示在浏览器的页面上。
1.2. 配置URLconf
配置URL,建立url地址和视图的对应关系。一般在视图views.py所在的应用的文件夹下新建一个urls.py用来配置URL,再到项目的urls.py将其导入。
查找视图的过程(了解)
- 请求者在浏览器地址栏中输入url,
- 网站得到请求后,获取url信息 ,然后与编写好的URLconf逐条匹配,
- 如果匹配成功则调用对应的视图函数,如果所有的URLconf都没有匹配成功,则返回404错误。
- (举例说明见官方文档,仔细阅读)
一条URLconf包括url规则、视图:
- url规则使用正则表达式定义(Django2之前的用法,之后的不推荐)
- Django2之后推荐使用path函数
- 视图就是在views.py中定义的视图函数。
需要两步完成URLconf配置:
- 1.在应用中定义URLconf
- 2.包含到项目的URLconf中
注意:
一般应用的视图不直接在项目的urls.py配置,而是在应用目录下的urls.py配置,再到项目的urls.py将其include进来。
快捷方式:render()函数
在实际运用中,加载模板、传递参数,返回HttpResponse对象是一整套再常用不过的操作了,为了节省力气,Django提供了一个快捷方式:render函数,一步到位!就不再需要导入 loader
和 HttpResponse
,而是从django.shortcuts
导入了render。
- render()函数的第一个位置参数是请求对象(就是view函数的第一个参数),
- 第二个位置参数是模板。
- 还可以有一个可选的第三参数,一个包含需要传递给模板的数据的字典。
- 最后render函数返回一个经过字典数据渲染过的模板封装而成的HttpResponse对象。
快捷方式:get_object_or_404()
就像render函数一样,Django提供get_object_or_404()方法,用来返回404。别忘了先从Django内置的快捷方式模块中导出get_object_or_404()。
get_object_or_404()
方法第一个位置参数为一个Django模型,- 后面可以跟上任意个数的关键字参数,如果对象不存在则弹出Http404错误。
- 详见
get_object_or_404()
也有 get_list_or_404()
函数,工作原理和 get_object_or_404()
一样,除了 get()
函数被换成了 filter()
函数。如果列表为空的话会抛出 Http404
异常。
(filter是模型API中用来过滤查询结果的函数,它的结果是一个列表集。而get则是查询一个结果的方法,和filter是一个和多个的区别!)
2.模版
在Django中,将前端的内容定义在模板中,然后再把模板交给视图调用,各种漂亮、炫酷的效果就出现了。
2.1. 创建模板
- 创建模版文件
- 配置模版目录
1. 创建模版文件
模版放在项目根目录的 templates 目录下,建议在每个应用再建立一个同名目录用于放置其模版文件。
类似如下目录结构:
项目名
└──...
└── templates
└── 应用名
| ├── 模板1
| └── 模板2
└── 应用名2
├── 模板21
└── 模板22
在模板中输出变量语法如下,变量可能是从视图中传递过来的,也可能是在模板中定义的。
{{变量名}}
在模板中编写代码段语法如下:{%代码段%}
2. 配置模版目录
设置查找模板的路径:打开项目的配置文件settings.py文件,设置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],
(注:使用拼接,BASE_DIR是项目的目录)
2.2. 视图调用模板
视图调用模板分为三步骤:
- 找到模板:即加载模版文件。比如去模版目录下面获取html文件的内容,得到一个模板对象。
- 用from django.template import loader,loader.get_template()
- 定义模版上下文:向模板文件传递数据。
用from django.template import RequestContext, RequestContext() 函数(Django2.x实测失效,报错context must be a dict rather than RequestContext. 。原因是新的版本中,上下文应该是dict)- 更新:定义一个字典作为上下文,如空字典 {}
- 渲染模板:得到标准的html内容。
- 用template.render(context)
视图调用模板都要执行以上三部分,为了减少开发人员重复编写加载、渲染的代码,Django提供了一个快捷函数: render()
,用于调用模板。方法 render()
包含3个参数:
- 第一个参数为request对象
- 第二个参数为模板文件路径
- 第三个参数为字典,表示向模板中传递的上下文数据
2.3. 删除模板中硬编码的URLs
在模板中编写链接时,如果链接是硬编码的,对于代码修改非常不利。
硬编码和强耦合的链接,对于一个包含很多应用的项目来说,修改起来是十分困难的。
只要给urls定义一个name别名,就可以用它来解决这个问题。
只要在 应用
.urls
的url()
函数中通过 name 参数为 URL 定义了名字,就可以使用{% url %}
标签代替它:比如:<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
Django就会在应用的
urls
文件中查找name='detail'
的url,具体的就是下面这行:path('<int:question_id>/', views.detail, name='detail'),
这样,视图的url即使改变,模版也不用做修改了。
3. 为 URL 名称添加命名空间
Django区分同一个项目多个app之间的URL name?Django 如何知道 {% url %}
标签到底对应哪一个应用的 URL 呢?
答:使用URLconf的命名空间。在根 URLconf 中添加命名空间。加上 app_name
设置命名空间。
如:在polls应用的 polls/urls.py
文件中,加上 app_name
设置命名空间,即在urlpatterns外加一句:app_name = 'polls'
完整的是这样:
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'),
]
这样,在模板中就可以将 {% url 'detail' question.id %} 改为 {% url 'polls:detail' question.id %} 。
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
注:在项目的urls.py中,include应用的urls.py时,也可以加上namespace,
如:path('polls/', include('polls.urls', namespace='polls')),
-----end-----