1. 模板
如果使用react实现前端页面,其实Django就没有必须使用模板,它其实就是一个纯后台服务程序,接收请求,响应数据,前后端接口设计就可以是纯粹的Restful风格。 模板的目的就是为了可视化,将数据按照一定布局格式输出,而不是为了数据处理,所以一般不会有复杂的处理逻 辑。模板的引入实现了业务逻辑和显示格式的分离。这样,在开发中,就可以分工协作,页面开发完成页面布局设 计,后台开发完成数据处理逻辑的实现。 Python的模板引擎默认使用Django template language (DTL)构建。
1.1 模板配置
在settings.py中,设置模板项目的路径:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 列表的意思是有先后顺序
'APP_DIRS': True, # 管理app的路径们
'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',
],
},
},
]
- DIRS:列表,定义模板文件的搜索路径顺序。os.path.join(BASE_DIR, 'templates')即项目根目录下templates 目录,请构建这个目录。
- APP_DIRS:是否运行在每个已经安装的应用中查找模板。应用自己目录下有templates目录,例如 django/contrib/admin/templates。如果应用需要可分离、可重用,建议把模板放到应用目录下
- BASE_DIR 是 项目根目录,os.path.join(BASE_DIR, 'templates')就是在manage.py这一层建立一个目录 templates。这个路径就是以后默认找模板的地方。
1.2 模板渲染
模板页:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>金州勇士</title>
</head>
<body>
我是模板,数据是{{content}}
</body>
</html>
将模板index.html放入到templates目录下
模板处理:
- 加载模板:模板是一个文件,需要从磁盘读取并加载。要将模板放置在
- 渲染:模板需要使用内容数据来渲染,生成HTML文件内容
from django.template import loader
from django.http import HttpRequest, HttpResponse
def index(request: HttpRequest):
"""视图函数:请求进来返回响应"""
template = loader.get_template('index.html') # 加载器模块搜索模板并加载它
print(template.origin) # 显示模板路径
context = {'content': 'www.magedu.com'} # 数据字典
return HttpResponse(template.render(context, request))
render快捷渲染函数 :上面2个步骤代码编写繁琐,Django提供了对其的封装——快捷函数render。render(request, template_name, context=None) 返回HttpResponse对象,template_name模板名称, context 数据字典 ,render_to_string()是其核心方法,其实就是拿数据替换HTML中的指定位置后返回一个字符串。
from django.http import HttpRequest
from django.shortcuts import render
def index(request: HttpRequest):
"""视图函数:请求进来返回响应"""
return render(request, 'index.html', {'content': 'www.magedu.com'})
2.DTL语法
2.1 变量
语法 {{ variable }} 变量名由字母、数字、下划线、点号组成。
点号使用的时候,例如foo.bar,遵循以下顺序:
- 字典查找,例如foo["bar"],把foo当做字典,bar当做key
- 属性或方法的查找,例如foo.bar,把foo当做对象,bar当做属性或方法
- 数字索引查找,例如foo[bar],把foo当做列表一样,使用索引访问
from django.http import HttpRequest # , HttpResponse # , JsonResponse
# from django.template import loader
from django.shortcuts import render
import datetime
def index(request: HttpRequest):
"""视图函数:请求进来返回响应"""
# return HttpResponse(b"welcome to Golden State Warriors!")
# d = {}
# d['method'] = request.path
# d['path'] = request.path
# d['path_info'] = request.path_info
# d['qs'] = request.GET
#
# return JsonResponse(d, status=201)
# template = loader.get_template('index.html') # 加载器模板搜索模板并加载它
# print(template.origin) # 显示模板路径
# context = {'content': 'www.magedu.com'} # 数据字典
#
# return HttpResponse(template.render(context, request))
# abc = "我是内容".encode()
# res = HttpResponse(b'<html><body>' + abc + b'</body></html>') # 这样写太麻烦了,早就不用这么写了
# return res
# my_dict = {
# 'a': 1,
# 'b': 0,
# 'c': list('abcdefghijklmn'),
# 'e': list(range(1, 10)),
# 'd': {'x': 1000, 'y': 200},
# 'date': datetime.datetime.now()
# }
#
new_dict = {
'a': 100,
'b': 0,
'c': list(range(10, 20)),
'd': 'abc',
'date': datetime.datetime.now(),
'f': list(range(1, 10))
}
# content = {
# 'a': 100,
# 'b': 0,
# 'c': list(range(10)),
# 'd': {'x': 1000, 'y': 200},
# 'date': datetime.datetime.now()
# }
# res = render(request, 'index.html', content)
# return res
# context = {'content': 'www.magedu.com', 'my_dict': my_dict}
context = {'content': 'www.magedu.com', 'new_dict': new_dict}
return render(request, 'index.html', context)
注意:如果变量未能找到,则缺省插入空字符串'',在模板中调用方法,不能加小括号,自然也不能传递参数。
2.2 模板标签
2.3 注释标签
单行注释 {# #}。多行注释 {% comment %} ... {% endcomment %}.
2.4 过滤器
语法 {{ 变量|过滤器 }}
过滤器使用管道字符 | ,例如 {{ name|lower }} , {{ name }} 变量被过滤器 lower 处理后,文档大写转换文本为小写。过滤管道可以被套接 ,一个过滤器管道的输出又可以作为下一个管道的输入。例如 {{ my_list|first|upper }} ,将列表第一个元素并将其转化为大写。
过滤器传参:有些过滤器可以传递参数,过滤器的参数跟随冒号之后并且总是以双引号包含。 例如: {{ bio|truncatewords:"30" }} ,截取显示变量 bio 的前30个词。 {{ my_list|join:"," }} ,将my_list的所有元素使用,逗号连接起来。
模板的练习:
1、奇偶行列表输出:
使用下面字典my_dict的c的列表,在模板网页中列表ul输出多行数据要求奇偶行颜色不同;每行有行号(从1开始); 列表中所有数据都增大100。
2、打印九九方阵 :使用把上面所有的数学表达式放到HTML表格对应的格子中。如果可以,请实现奇偶行颜色不同。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>金州勇士</title>
<style>
#sqs{
color: red;
}
#cy{
color: green;
}
table{
border-collapse:collapse;
text-align:center;
}
#ltz{
border: 1px solid black;
color: red;
}
#xyt{
border: 1px solid black;
color: green;
}
#sq{
border: 1px solid black;
color: red;
}
#qs{
border: 1px solid black;
color: blue;
}
</style>
</head>
<body>
<ul>
{% for x in new_dict.c %}
{% if forloop.counter|divisibleby:"2" %}
<li id="sqs">
{{ forloop.counter }}: {{ x|add:"100"}}
</li>
{% else %}
<li id="cy">
{{ forloop.counter }}: {{ x|add:"100" }}
</li>
{% endif %}
{% endfor %}
</ul>
<table id="lss">
{% for i in new_dict.f %}
<tr>
{% if forloop.counter|divisibleby:2 %}
{% for j in new_dict.f %}
<td id="ltz">
{{ i }} * {{ j }} = {% widthratio i 1 j %}
</td>
{% endfor %}
{% else %}
{% for j in new_dict.f %}
<td id="xyt">
{{ i }} * {{ j }} = {% widthratio i 1 j %}
</td>
{% endfor %}
{% endif %}
</tr>
{% endfor %}
</table>
<br/>
<table id="lyf">
{% for i in new_dict.f %}
<tr>
{% if forloop.counter|divisibleby:2 %}
{% for j in new_dict.f %}
{% if j <= i %}
<td id="sq">
{{ i }} * {{ j }} = {% widthratio i 1 j %}
</td>
{% endif %}
{% endfor %}
{% else %}
{% for j in new_dict.f %}
{% if j <= i %}
<td id="qs">
{{ i }} * {{ j }} = {% widthratio i 1 j %}
</td>
{% endif %}
{% endfor %}
{% endif %}
</tr>
{% endfor %}
</table>
</body>
</html>