概述
模板(template)可以便利地生成HTML,实现了业务逻辑(views)和显示内容(template)的分离,一个视图可以使用任意一个模板,一个模板也可以供多个视图使用。模板一般包含静态的HTML部分和动态渲染部分。
使用模板来渲染内容
- 创建一个tmpl项目和一个learn应用:
django-admin.py startproject tmpl
cd tmpl
python manage.py startapp learn
- 将learn添加到settings.py中的INSTALLED_APPS(相当于注册该应用):
- 打开learn/views.py,写一个首页的视图:
from django.shortcuts import render
def home(request):
return render(request, 'home.html')
- 在learn目录下新建一个templates文件夹,在里面创建一个home.html文件。
在默认配置下,django中的模板系统会自动找到app下面的templates文件夹中的模板文件。
现在目录结构是这样的:
- 在home.html中添加内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome</title>
</head>
<body>
Welcome!
</body>
</html>
- 将视图函数与url相关联,在urls.py中添加:
from django.contrib import admin
from django.urls import path
from learn import views as learn_views
urlpatterns = [
path('admin/', admin.site.urls),
path('', learn_views.home, name='home')
]
- 启动服务器,可以看到:
基本模板使用语法
- 变量:{{ 变量名 }}
- 标签:{% 代码块 %}
- 过滤器:|(竖线,管道符)
- 注释:{# 注释部分 #}
使用实例
显示一个字符串到网页上
在views.py中:
from django.shortcuts import render
def home(request):
string = ‘正在学习Django建站!’
return render(request, ‘home.html’, {‘string’: string})
在这个函数中,我们传递了一个string变量到模板中,模板中可以直接使用它:
{{string}}
for循环的使用
views.py:
from django.shortcuts import render
def home(request):
list = ["HTML", "CSS", "jQuery", "Python", "Django"]
return render(request, 'home.html', {'list': list})
在home.html中:
{% for item in list %}
{{item}}
{% endfor %}
显示字典中的内容
views.py:
def home(request):
dict = {
'site': 'home',
'content': 'IT'
}
return render(request, 'home.html', {'dict': dict})
home.html:
site:{{dict.site}}
content:{{dict.content}}
注意,这里是用点( . )来取得键对应的值,而不是中括号。
进行if判断和for循环
views.py:
def home(request):
List = map(str, range(100))# 一个长度为100的 List
return render(request, 'home.html', {'List': List})
假如我们使用逗号将他们连接起来,但是又不想让最后一个元素后面出现逗号:
{% for item in List %}
{{ item }}{% if not forloop.last %},{% endif %}
{% endfor %}
在for循环中还有很多有用的变量:
模板中的逻辑操作
在模板中,>、==、!=、>=等运算符都可以在模板中使用。
views.py:
def home(request):
score = 50
return render(request, 'home.html', {'score': score})
home.html:
{% if score >= 60 %}
及格
{% else %}
不及格
{% endif %}
and、or、not 、in等运算符也可以在模板中使用。
{% if num <= 100 and num >= 0 %}
num在0到100之间
{% else %}
数值不在范围之内!
{% endif %}
获取当前用户、当前网址等
获取当前用户:
{{request.user}}
获取当前网址:
{{request.path}}
获取当前GET参数:
{{request.GET.urlencode}}
模板继承
很多网页设计中,页头、页脚和导航栏等设计多数是一样的,我们可以把通用的部分抽出来,做成父模板;然后在子模板中继承父模板,在实现其中各自的差异。
可以写一个base.html来包含它们:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}默认标题{% endblock %} </title>
</head>
<body>
{% include 'nav.html' %}
{% block content %}
<div>这里是默认内容</div>
{% endblock %}
{% include 'bottom.html' %}
{% include 'count.html' %}
</body>
</html>
其中:
- block标签:在父模板中预留区域,在子模板中进行填充。可以定义默认值。
- include:包含其他文件的内容,即将网页的共同部分拿出来重复利用。
其他的页面可以继承base.html。比如首页home.html:
{% extends 'base.html' %}
{% block title %}欢迎光临首页{% endblock %}
{% block content %}
{% include 'ad.html' %}
这里是首页,欢迎光临
{% endblock %}
注意:模板一般放在app中的templates文件夹下,django会自动到这个文件中去找。但是假如每个app的templates下都有一个index.html,当我们在views.py中使用的时候,直接写一个render(request,‘index.html’),django查找就会出错。
Django模板查找机制:
查找模板的过程是在每个app的templates文件夹下找,而不是当前app中的代码就在当前app的templates中找,各个app的templates形成一个文件夹列表,django遍历这个列表进行寻找。这么做的好处是一个app可以使用另一个app的模板文件,但也会出现查找出错的问题。
解决方法:把每个app中的templates文件夹中再建一个app的名称,仅和该app相关的模板放在app/templates/app/目录下。