Loading

006 Django 模板层

模板层

模板配置

  • 创建模板文件夹 <项目名>/templates
  • settings.pyTEMPLATES 配置项
    • BACKEND: 指定模板的引擎
    • DIRS: 模板的搜索目录(可以是一个也可以是多个)
    • APP_DIRS: 是否要在应用中的 templates 文件夹中搜索模板文件
    • OPTIONS: 有关模板的选项
  • 配置项中需要修改的部分
    • 设置DIRS - ‘DIRS’:[os.path.join(BASE_DIR, ‘templates’)]

例子

  1. 未添加之前

  2. 创建之后

默认没有添加os标准库,请自行在 settings.py 文件的顶部添加

  1. 回到项目的根目录,创建一个templates文件夹

image-20220622161052879

image-20220622161102799

加载模板

loader方法

我们通过 loader 获取模板,通过 HttpResponse 进行响应,在视图函数中

from django.template import loader

# 通过loader加载模板
t = loader.get_template("模板文件名")

# 将 t 转换成 HTML 字符串
html = t.render(字典数据)

# 用响应对象将转换的字符串内容返回给浏览器
return HttpResponse(html)

例子

  1. 在模板文件夹中添加我们需要的新页面 test_html.html

image-20220622162253155

  1. 在视图层添加一个新的函数用来读取我们的模板
# views.py 文件内
from django.template import loader
from django.http import HttpResponse

def test_html(request):
    t = loader.get_template("test_html.html")
    
    html = t.render()
    
    return HttpResponse(html)
  1. 在路由文件内添加地址
# urls.py 文件内
from django.urls import path
from . import views

urlpatterns = [
    path('testHtml',views.test_html)
]
  1. 浏览地址打开

image-20220622162831418

render方法(推荐)

我们可以使用 render()直接加载并且响应模板

在视图文件中

from django.shortcuts import render
return render(request, "模板文件名",字典数据)

例子

  1. 在模板文件夹中添加我们需要的新页面 test_html.html

image-20220622162253155

  1. 在视图层添加一个新的函数用来读取我们的模板此处进行了简化和包装
# views.py 文件内
from django.shortcuts import render
from django.http import HttpResponse

def test_html(request):
    # 注意这里进行了简化和包装
	return render(request, "test_html,html")
  1. 在路由文件内添加地址
# urls.py 文件内
from django.urls import path
from . import views

urlpatterns = [
    path('testHtml',views.test_html)
]
  1. 浏览地址打开

image-20220622162831418

视图与模板层之间的交互

  1. 视图函数中可以将 Python 变量封装到字典中传递到模板

样例:

def xxx_view(request):
    dic = {
        "变量1":"值1",
        " 变量2":"值2"
    }
    return render(request,'xxx.html',dic)
  1. 在模板中我们则可以使用 {{变量名}}这样的方法调用视图传递进来的变量

使用模板例子

  1. 设置视图层函数,在视图层定义指定字典然后通过render()函数传递出去
# views.py文件内
from django.shortcuts import render

def testTemplate(request):
    dic = {
        "name":"张飞",
        "age":"18"
    }
    return render(request,"test_template.html",dic)
  1. 新建 HTML 文件

image-20220622164453904

  1. 设置路由
# urls.py 文件内
from django.urls import path
from . import views

urlpatterns = [
    path('testTemplate', views.test_template),
]
  1. 打开网页发现内容已经被填充到网页

image-20220622164621019

模板的变量

能够传递到模板中的数据类型不止 dict,其他的数据类型同样可以传递

类型 说明
str 字符串
int 整型
list 数组
tuple 元组
dict 字典
func 方法
obj 类实例化的对象
  • 如果传入的是一个列表
    • 使用 {{ 变量名.index }}的方式调用,而不是 变量名[index]
  • 如果传进来的字典内部还有一个字典
    • 使用 {{ 变量名.key }}来调用对应的值
  • 如果传入的是一个实例化的对象
    • 使用{{ 对象.方法 }} 来调用
  • 如果传入的是一个函数
    • 使用 {{函数名}}在模板中就会直接调用函数并且返回返回值
  1. 视图函数中设置的 dic

image-20220622165528397

  1. 模板 html 文件内的内容

image-20220622165639795

  1. 最终页面的内容

image-20220622165713343

模板标签

作用:将一些服务器端的功能嵌入到模板中,例如流程控制等

标签语法:

{% 标签 %}
...
{% 结束标签 %}

if 标签

{% if条件表达式1 %}
...
{% elif条件表达式2 %}
...
{% elif条件表达式3 %} 
...
{% else %}
...
{% endif %}
  • if条件表达式里可以用的运算符==,!=,<,>, <=, >=, in, not,in, is, is not, not、 and、or
  • 在if标记中使用实际括号是无效的语法。如果您需要它们指示优先级,则应使用嵌套的if标记。

可视化计算器练习

  1. 创建 mycal.html 页面
<form action='/mycal' method='post'>
        <input type='text' name="x" value={{ x }}>
        <select name='op'>
            <option value="add"> +加</option>
            <option value="sub"> -减</option>
            <option value="mul"> *乘</option>
            <option value="div"> /除</option>
        </select>
        <input type='text' name="y" value={{ y }}> = <span>{{ result }}</span>
        <div>
            <input type="submit" value='开始计算'>
        </div>
    </form>
  1. 在视图界面创建一个函数负责接收计算然后返回页面
# views,py 文件内
from django.shortcuts import render

def my_cal(request):
    # 获取数值
    if request.method == "POST":
        x = int(request.POST.get("x",'0'))
        y = int(request.POST.get("y",'0'))
        op = request.POST.get("op",'add')
        
        if op == 'add':
            result = str(x + y)
    
        elif op == 'sub':
            result = str(x - y)
        
        elif op == 'mul':
            result = str(x * y)
        
        elif op == 'div':
            result = str(x / y)
    
        # 创建字典返回给页面
        dic = {
            'result': result,
            'y': y,
            'x': x,
        }
        
        return render(request,'mycal.html',dic)
    
    return render(request,"mycal.html")
  1. 在路由内设置
# urls.py 文件内
from django.urls import path
from . import views

urlpatterns = [
    path('testTemplate', views.test_template)
]
  1. 页面内查看效果

655a246d-07ce-42c1-b92e-4e7b162635c3

  1. 小技巧

我们在拼接字典的过程中绝对非常麻烦的可以尝试使用 python自带的函数 locals(),可以把当前函数内的变量打包成字典,就可以直接返回给我们的前端

loacls() 使用
def a():
    a = 1
    b = 2
    c = {'a': 1, 'b':4}
    return locals()

print(a())
  • 最终打印的结果
{'a': 1, 'b': 2, 'c': {'a': 1, 'b': 4}}
  • 我们使用 locals() 后就不需要我们再手动写字典了
def my_cal(request):
    # 获取数值
    if request.method == "POST":
        x = int(request.POST.get("x",'0'))
        y = int(request.POST.get("y",'0'))
        op = request.POST.get("op",'add')
        
        if op == 'add':
            result = str(x + y)
    
        elif op == 'sub':
            result = str(x - y)
        
        elif op == 'mul':
            result = str(x * y)
        
        elif op == 'div':
            result = str(x / y)
      
        # 此处我们就直接传入 locals()即可
        return render(request,'mycal.html',locals())
    
    return render(request,"mycal.html")

for 标签

{% for变量in可迭代对象%}
... 循环语句
{% empty %}
... 可迭代对象无数据时填充的语句
{% endfor %}

其中的 empty 表示的如果我们的可迭代对象是空,django就会显示我们的empty下面的内容

内置变量 forloop

这些变量都需要写在 for 循环内部,如果写在外部就直接报错

变量 说明
forloop.counter 循环的当前迭代(从1开始索引)
forloop.counter0 循环的当前迭代(从0开始索引)
forloop.revcounter counter值的倒序
orloop.revcounter0 revcounter值的倒序
forloop.first 如果这是第一次通过循环,则为真
forloop.last 如果这是最后一次循环, 则为真
forloop.parentloop 当嵌套循环,parentloop 表示外层循环

for 循环例子1

  1. 给 HTML 模板(创建文件 testfor.html)
{% for i in name %}
    <p>{{i}}</p>
    {% empty %}
    当前没有发现任贺数据
    {% endfor %}
  1. 给我们的视图添加函数
# views.py 文件内
from django.shortcuts import render

def testfor(request):   
    name = ['虎晶瑶','胡奇迈','闭昆皓','黄蝶']
    return render(request,'testfor.html',locals())
  1. 添加路由
# urls.py 文件内
from django.urls import path
from . import views

urlpatterns = [
    path('testfor',views.testfor)
]
  1. 查看页面

image-20220622175953121

for 循环例子2

我们在上面的基础上添加一些新的需求,使用我们的forloop变量

  1. 我们循环的第一次打印打印头 if forloop.first
{% for i in name %}

{% if forloop.first %} 当前是第一次循环 {% endif %}

<p>{{i}}</p>
{% empty %}
当前没有发现任贺数据
{% endfor %}

image-20220622180244482

  1. 我们结尾的时候也打印特殊的内容 if forloop.last
{% for i in name %}
    
{% if forloop.first %} 当前是第一次循环 {% endif %}

<p>{{i}}</p>

{% if forloop.last %} 当前循环结束了 {% endif %}

{% empty %}
当前没有发现任贺数据  
{% endfor %}

image-20220622180505814

  1. 打印我们当前的项是第几个 {{forloop.counter}}
{% for i in name %}
    
    {% if forloop.first %} 当前是第一次循环 {% endif %}
    
    <p>{{forloop.counter}} {{i}}</p>
    
    {% if forloop.last %} 当前循环结束了 {% endif %}
    
    {% empty %}
    当前没有发现任贺数据  
    {% endfor %}

image-20220622180700803

模板过滤器

  • 定义:在变量输出时对变量的值进行处理
  • 作用:可以通过使用过滤器来改变变量的输出显示
  • 语法:{{变量|过滤器1:'参数值1|过滤器2:'参数值2'}}

常用模板过滤器

模板过滤器 说明
lower 将字符串转换为全部小写。
upper 将字符串转换为大写形式
safe 默认不对变量内的字符串进行htmI转义
add: "n" 将value的值增加n
truncatechars:'n' 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(...") 结尾。

upper 模板过滤器

  1. 没有加模板过滤器之前
<h3>str 是{{ str }}</h3>

image-20220622181353074

  1. 添加模板过滤器之后
<h3>str 是{{ str|upper }}</h3>

image-20220622181501177

add 模板过滤器

  1. 没有加模板过滤器之前
<h3>int是{{ int }}</h3>

image-20220622181644785

  1. 添加模板过滤器之后
<h3>int是{{ int|add:"2" }}</h3>

image-20220622181746679

模板的继承

image-20220622182021252

大多数的网站头部和尾部基本都是一样的,我们这个时候就可以使用模板的继承来让一个页面内相同的内容继承

模板继承可以使父模板的内容重用,子模板直接继承父模板的全部内容并可以覆盖父模板中相应的块

语法-父模板中:

  • 定义父模板中的块block标签
  • 标识出哪些在子模块中是允许被修改的
  • block标签:在父模板中定义,可以在子模板中覆盖

语法 - 子模板中:

  • 继承模板extends标签(写在模板文件的第一行)
    • 例如{% extends 'base.html' %}
  • 子模板重写父模板中的内容块
    • {% block block_ name %}
      子模板块用来覆盖父模板中block_ name块的内容
      {% endblock %}

例子

  1. 新建一个父模板 base_index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    {% block title %}
    
    <title>Document</title>
    
    {% endblock %}
</head>
<body>
<!-- 导航条 -->

    <a href="/music">音乐频道</a>
    <a href="/base_index">返回首页</a>

    {% block content %}

    <p>这里是首页</p>
    <p>这里是首页</p>

    {% endblock %}

    <p>页尾:如果有问题请联系xxx</p>
    
</body>
</html>
  1. 创建子模板 music.html,然后删除所有 html 元素,并且在最开头继承我们的父模板
{% extends "base_index.html" %}

{% block title %}
<title>这里是音乐页面</title>

{% endblock %}

{% block content %}

<p>这是音乐页面</p>

{% endblock %}
  1. 新建视图函数
# views.py 文件内
from django.shortcuts import render

def base_index(request):
    return render(request,'base_index.html')

def music(request):
    return render(request,'music.html')
  1. 在主路由内添加我们的路由记录
# urls.py 文件内
from django.urls import path, re_path
from . import views

urlpatterns = [
        path('base_index',views.base_index),
    	path('music',views.music)
]
  1. 打开浏览器查看效果

d7d8f741-f592-4f2d-9a24-d3b692824076

posted @ 2022-07-10 19:16  271374667  阅读(5)  评论(0编辑  收藏  举报