在视图函数里返回的是一个 HttpResponse
类的实例,我们给它传入了一个希望显示在用户浏览器上的字符串。但是我们的博客不可能只显示这么一句话,它有可能会显示很长很长的内容。比如我们发布的博客文章列表,或者一大段的博客文章。我们不能每次都把这些大段大段的内容传给HttpResponse
。
Django 对这个问题给我们提供了一个很好的解决方案,叫做模板系统。Django 要我们把大段的文本写到一个文件里,然后 Django 自己会去读取这个文件,再把读取到的内容传给 HttpResponse
。让我们用模板系统来改造一下上面的例子。
- 创建模板template/blog/index.html 在工程目录文件夹下创建一个templates目录(即templates目录和manage.py同级),改template文件夹用于存储模板,然后再templates创建blog文件夹,templates/blog用于创建应用blog的模板,在templates/blog创建一个空文件index.html.。这样可以区分不同应用的模板。
- 编辑template/blog/index.html文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ welcome }}</h1>
</body>
</html>
-
这是一个标准的 HTML 文档,只是里面有两个比较奇怪的地方:
{{ title }}
,{{ welcome }}
。这是 Django 规定的语法。用 {{ }} 包起来的变量叫做模板变量。Django 在渲染这个模板的时候会根据我们传递给模板的变量替换掉这些变量。最终在模板中显示的将会是我们传递的值。注意:index.html 必须以 UTF-8 的编码格式保存,且小心不要往里面添加一些特殊字符,否则极有可能得到一个 UnicodeDecodeError 这样的错误。
- 编辑template/blog/index.html文件如下:
- 修改配置项settings.py告诉django从哪里查找模板
在 settings.py 找到
TEMPLATES
选项,在DIRS里面添加:os.path.join(BASE_DIR, 'templates')修改它的内容是这样的注意BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))), BASE_DIR就是manage.py的父目录
- 所以要求templates是和manage.py是同级
- 修改视图函数
blog/views.py from django.http import HttpResponse
from django.shortcuts import render def index(request):
return render(request, 'blog/index.html', context={
'title': '我的博客首页',
'welcome': '欢迎访问我的博客首页'
})- 这里我们不再是直接把字符串传给
HttpResponse
了,而是调用 Django 提供的render
函数。这个函数根据我们传入的参数来构造HttpResponse
。我们首先把 HTTP 请求传了进去,然后
render
根据第二个参数的值 blog/index.html 找到这个模板文件并读取模板中的内容。之后render
根据我们传入的context
参数的值把模板中的变量替换为我们传递的变量的值,{{ title }}
被替换成了context
字典中title
对应的值,同理{{ welcome }}
也被替换成相应的值。最终,我们的 HTML 模板中的内容字符串被传递给
HttpResponse
对象并返回给浏览器(Django 在render
函数里隐式地帮我们完成了这个过程),这样用户的浏览器上便显示出了我们写的 HTML 模板的内容。