继承这个概念在很多语言中都有,主要是子类从父类继承一些属性和函数,当然子类也可以重写父类函数的一些功能等等。在Django也有类似功能,这里的继承是指子类继承了父类的“界面布局”
1.概述
Django中模板层就是Modle层,其模式为MTV(Model-Template-View)
- M 模型层 负责与数据库交互
- T 模板层 负责呈现内容到浏览器
- V 视图层 是核心,负责接收请求,获取数据,返回结果
创建模板文件夹,一般在<项目名称>/templates创建普通文件夹
因此这里的template为项目名称为mysite1的第一层子目录
在settings.py中
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')], #修改DIRS目录指向新创建的文件夹
这里在settings.py中先关闭crsf防范网络攻击
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
2.模板加载
模板templates下的***.html文件先后有两种加载方式
- 1.通过loader进行加载
from django.template import loader
# 通过loader加载模板
t = loader.get_template(模板名称)
# 将t转换成 HTML 字符串
html = t.render(字典数据)
# 用响应对象将转换的字符串内容返回给浏览器
return HttpResponse(html)
这种是早期的django使用loader.render方式加载,发现太麻烦,因此有了第二个版本实现方案进行加载
- 2.通过render进行加载(推荐使用)
from django.shortcuts import render
return render(request,模板名称,字典数据)
3.视图层与模板层交互
视图函数view.py中可以将python变量封装到字典中传递给模板层进行展示
模板层,使用 {{ 变量名 }}获取变量的值
#views.py中新增test_html视图函数
def test_html(request):
# 方案1
# from django.template import loader
# t = loader.get_template('test_html.html')
# html = t.render()
# return HttpResponse(html)
#方案2
from django.shortcuts import render
dic = {'username':'rhx','age':18}
return render(request,'test_html.html',dic)
模板层新增test_html.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>{{ username }}是模板层的~~~~</h3>
</body>
</html>
路由函数urls.py绑定视图和模板函数
path('test_html',views.test_html),
4.模板标签
能传递到模板中的数据类型
str字符串,int整形,list列表,tuple元组,dict字典,func函数,obj类实例化对象。在模板中使用的变量语法为:
- {{ 变量名 }}
- {{ 变量名.index }}
- {{ 变量名.key }}
- {{ 对象.方法 }}
- {{ 函数名 }}
def test_html_param(request):
from django.shortcuts import render
dic = {}
dic['int'] = 88
dic['str'] = 'rhx'
dic['list'] = ['Tom','Jack','Lily']
dic['dict'] = {'a':9,'b':10}
# 这类注意如果是传递的函数,这里只传递函数名,如果是say_hi()相当于传递的是hahaha字符串
dic['func'] = say_hi
dic['class_obj'] = Dog()
return render(request,"test_html_param.html",dic)
输出如下所示
5.模板层继承
参考豆瓣电影中布局,整体把界面分成上中下三个部分,选择电影和电视剧的时候,仅仅是标题和中间部分的不同
如上所示,这种情况下我们写一个base.html,之后每一个sheet都从base继承,修改body中的部分即可。
其语法是:
- 定义父模板中的block块标签
- 标识出哪些在子模块中是可以修改是允许被修改的
- block标签,子父标签中定义,可以在子模板中覆盖
- 子模板中继承模板使用 {% extends ‘base.html’ %},子模板重写父模板中的block块,语法如下
{% block block_name %} 子模板中的内容 {% endblock block_name %}
这里举例说明:
创建base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{% block mytitle %}
<title>主页</title>
{% endblock %}
</head>
<body>
<a href="/music_index">音乐频道</a>
<a href="/sport_index">体育频道</a>
<br>
{% block info %}
这是主页
{% endblock %}
<br>
<h3>有任何问题请联系400-2000-3842</h3>
</body>
</html>
创建两个子模板音乐和体育继承于父模板
music.html
{% extends 'base.html' %}
{% block mytitle %}
<title>音乐频道</title>
{% endblock %}
{% block info %}
欢迎来到音乐频道
{% endblock %}
sport.html
{% extends 'base.html' %}
{% block mytitle %}
<title>体育频道</title>
{% endblock %}
{% block info %}
欢迎来到体育频道
{% endblock %}
编写视图函数views.py
def base_view(request):
return render(request,'base.html')
def music_view(request):
return render(request,'music.html')
def sport_view(request):
return render(request,'sport.html')
配置路由信息urls.py
path("base_index",views.base_view),
path("sport_index",views.sport_view),
path("music_index",views.music_view),
输出结果如下: