AI智能
改变未来

Django 模板

[toc]

Django 模板

模板传值取值

后端传值

  • 键值对形式:
    {‘name’:value}

    精准传值,用啥传啥

  • 函数:
    locals()
      locals()

      将当前名称空间中所有的变量名全部传递给页面

    HTML取值

    • 变量相关:
      {{变量名}}
    • 逻辑相关:
      {% 表达式 %}

    在取值的时候需要注意以下几点

    * 传递函数名会自动加括号调用,并返回return后的值* 传递类名会自动加括号调用实例化成对象* 传递实例化对象名也返回对象,传递 对象.方法 可以获取该的返回值* 传递类和函数不需要加括号,自动加括号调用,模板语法不支持额外的传参(形参,实参)* HTML页面取值可以通过点`.`的方式取值,不论是索引还是键值等···eg:<p>{{ d.hobby.3.username }}</p># 索引就是.下标,字典就是.键
    <p>{{ my_int }}</p><p>{{ my_float }}</p><p>{{ my_list }}</p><p>{{ my_tuple }}</p><p>{{ my_dict }}</p><p>{{ my_set }}</p><p>{{ my_bool }}</p><p>{{ get_func }}</p><p>{{ MyClass }}</p><p>{{ obj.get_cls }}</p><p>{{ obj.get_self }}</p><p>{{ obj.get_static }}</p>
    def func(request):my_int = 123my_float = 3.14my_list = [1, 2, 3, 4]my_tuple = (1, 2, 3, 4,)my_dict = {\'name\': \'Hammer\'}my_set = {1, 2, 3, 4}my_bool = Truedef get_func():print(\'from get_func\')return \'get_func\'class MyClass(object):def get_self(self):return \'绑定给对象的方法\'@classmethoddef get_cls(cls):return \'绑定给类的方法\'@staticmethoddef get_static():return \'静态方法\'obj = MyClass()return render(request,\'func.html\',locals())

    过滤器

    模板语法:

    {{ 变量名 | 过滤器:可选参数 }}

    模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:

    {{ name|lower }}# 过滤器处理后转小写

    管道符的作用:一个过滤器管道的输出又可以作为下一个管道的输入

    default

    在html文件中,default 为变量提供一个默认值,如果views传的变量布尔值为false,则使用指定的默认值,如果为true,就使用views传的变量值;

    from django.shortcuts import renderdef func(request):id = 0return render(request,\'func.html\',locals()) # {\'id\':id}\'\'\'html\'\'\'<p>{{ id|default:\'views传的变量布尔值为false用我吧!\' }}</p>

    length

    • 返回对象的长度,适用于字符串和列表
    • 字典返回的是键值对的数量,集合返回的是去重后的长度
    字符串:{{ my_str|length }}列表:{{ my_list|length }}字典:{{ my_dict|length }}集合:{{ my_set|length }}
    def func(request):my_str = \'HammerZe\'my_list = [1, 2, 3, 4]my_dict = {\'name\': \'HammerZe\', \'age\': 18}my_set = {1, 1, 2, 2, 3, 3, 4, 4}return render(request, \'func.html\', locals())

    filesizeformat

    以更易读的方式显示文件的大小(即\’13 KB\’, \’4.1 MB\’, \’102 bytes\’等)

    字典返回的是键值对的数量,集合返回的是去重后的长度

    def func(request):file_data = 1024*1024return render(request, \'func.html\', locals())
    文件大小:{{ file_data|filesizeformat }}

    date

    根据给定格式对一个日期变量进行格式化。

    格式 Y-m-d H:i:s返回 年-月-日 小时:分钟:秒 的格式时间

    def func(request):import datetimectime = datetime.datetime.now()return render(request, \'func.html\', locals())
    时间:{{ ctime|date:\'Y-m-d H:i:s\' }}

    truncatechars

    如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分

    截断的字符串将以 结尾,

    ...

    也算三个字符,比如博客园首页示例

    def func(request):trun_str = \'HammerZe真帅\'return render(request, \'func.html\', locals())
    字符串截取:{{ trun_str|truncatechars:9 }}

    truncatewords

    该过滤器和

    truncatechars

    类似,但是

    ...

    不计入长度,空格为分隔符,一个单词为一个单元字符

    from django.shortcuts import renderdef func(request):trun_str = \'HammerZe Hans He\'return render(request, \'func.html\', locals())
    字符串截取:{{ trun_str|truncatewords:2 }}

    safe

    将字符串标记为安全,不需要转义。

    前端:要保证 views.py 传过来的数据绝对安全,才能用 safe。

    后端: 使用views.py 的 mark_safe 效果相同

    Django 会自动对 views.py 传到HTML文件中的标签语法进行转义,令其语义失效。加 safe 过滤器是告诉 Django 该数据是安全的,不必对其进行转义,可以让该数据语义生效(这里涉及到xss攻击自行查阅)

    from django.shortcuts import renderdef func(request):unsafe_str = \'<h1>不转义,语义失效,携带标签</h1>\'safe_str = \'<h1>转义,语义生效,我是一级标题</h1>\'# 后端取消转义from django.utils.safestring import mark_safesafe_str1 = mark_safe(\'<h1>后端取消转义</h1>\')return render(request, \'func.html\', locals())
    {{ unsafe_str }}{{ safe_str|safe }}{{ safe_str1 }}

    add

    整型做加法运算,字符串做拼接

    from django.shortcuts import renderdef func(request):add_num = 100join_str = \'Hammer\'return render(request, \'func.html\', locals())
    <p>加法运算:{{ add_num|add:100 }}</p><p>字符串拼接:{{ join_str|add:\'Ze\' }}</p>

    标签

    注释标签

    Django 注释使用

    {# 这是一个注释 #}

    if/else 标签

    • 语法格式:
    {% if condition %}... display{% endif %}或者{% if condition1 %}... display 1{% elif condition2 %}... display 2{% else %}... display 3{% endif %}# 示例{% if my_str %}{{ my_str }}{% endif %}def func(request):my_str = \'HammerZe\'return render(request, \'func.html\', locals())# 页面返回:HammerZe

    {% if %} 标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not ),例如:

    {% if a and b %}a 和 b 变量都是可用的。{% endif %}

    for 标签

    每一次循环中,模板系统会渲染在 {% for %}{% endfor %} 之间的所有内容;

    模板语法for循环和python 的for循环类似,支持

    in

    from django.shortcuts import renderdef func(request):l = [1,2,3,4]return render(request, \'func.html\', locals()){% for foo in l %}{{ foo }}{% endfor %}

    给标签增加一个

    reversed

    使得该列表被反向迭代

    {% for foo in l reversed  %}{{ foo }}{% endfor %}

    遍历字典: 可以直接用字典 .items 方法,用变量的解包分别获取键和值

    from django.shortcuts import renderdef func(request):my_dict = {\'name\': \'HammerZe\', \'age\': 18, \'gender\': \'male\'}return render(request, \'func.html\', locals())
    # 分别获取k,v{% for k in my_dict  %}{{ k }}{#{{ v }}#}{% endfor %}

    # 获取k,v{% for k,v in my_dict.items  %}{{ k }}{{ v }}{% endfor %}

    forloop内置对象

    {% for k in my_dict  %}{{ forloop }}{% endfor %}

    在 {% for %} 标签里可以通过 {{forloop}} 变量获取循环序号。

    • forloop.counter: 顺序获取循环序号,从 1 开始计算
    • forloop.counter0: 顺序获取循环序号,从 0 开始计算
    • forloop.revcounter: 倒序获取循环序号,结尾序号为 1
    • forloop.revcounter0: 倒序获取循环序号,结尾序号为 0
    • forloop.first(一般配合if标签使用): 第一条数据返回 True,其他数据返回 False
    • forloop.last(一般配合if标签使用): 最后一条数据返回 True,其他数据返回 False
    {% for i in views_list  %}{#<p>{{ forloop.counter }}</p>#} # 1 2 3 4 5{#<p>{{ forloop.counter0 }}</p>#} # 0 1 2 3 4{#<p>{{ forloop.revcounter }}</p>#} # 5 4 3 2 1{#<p>{{ forloop.revcounter0 }}</p>#} # 4 3 2 1 0<p>{{ forloop.first }}</p> # True False False False False<p>{{ forloop.last }}</p>  # False False False False True{% endfor %}from django.shortcuts import renderdef func(request):views_list = ["a", "b", "c", "d", "e"]return render(request, \'func.html\', locals())

    {% empty %}

    {% empty %} 从句:在循环为空的时候执行(即 in 后面的参数布尔值为 False )

    {% for i in views_list  %}}}{{ i }}{% empty %}空列表当然执行~{% endfor %}

    include 标签

    {% include %} 标签允许在模板中包含其它的模板的内容,类似后端导入模块

    {% include \'func2.html\'%}# func2.html<h1>哈哈哈</h1>

    csrf_token

    作用:跨站请求伪造保护。

    在我们使用form表单的时候,经常报403权限错误,这里我们可以在HTML页面使用

    {% csrf_token %}

    ,表单提交数据才会成功,或者在settings.py将中间件注释掉也可以;

    解析:

    首先,向服务器发送请求,获取登录页面,此时中间件 csrf 会自动生成一个隐藏input标签,该标签里的 value 属性的值是一个随机的字符串,用户获取到登录页面的同时也获取到了这个隐藏的input标签。

    然后,等用户需要用到form表单提交数据的时候,会携带这个 input 标签一起提交给中间件 csrf,原因是 form 表单提交数据时,会包括所有的 input 标签,中间件 csrf 接收到数据时,会判断,这个随机字符串是不是第一次它发给用户的那个,如果是,则数据提交成功,如果不是,则返回403权限错误。

    自定义过滤器

    1、在应用目录下创建 templatetags 目录名只能是 templatetags;

    2、在 templatetags 目录下创建任意 py 文件,如:my_tag.py

    3、my_tag.py 文件代码如下:

    from django import templateregister = template.Library()   #register的名字是固定的,不可改变

    4、利用装饰器

    @register.filter

    自定义过滤器

    注意:自定义过滤器也只能接收两个参数,因为

    |

    本质就是前面的参数交给后面过滤器处理,过滤器最强多可自带一个参数

    \'\'\'my_tag.py\'\'\'# 自定义过滤器@register.filter(name=\'myfilter\')def index(x,y):return x * y\'\'\'views.py\'\'\'from django.shortcuts import renderdef func(request):a=10return render(request, \'func.html\', locals())
    {#加载过滤器#}{% load my_tag %}{#使用过滤器#}{{ a|myfilter:10 }}

    5、自定义标签

    @register.simple_tag(name=\'mytag\')def tag(x, y, z):  # 自定义标签可以接收n个参数return x + y + z
    {#加载过滤器#}{% load my_tag %}{% mytag 1 2 3 %}

    自定义 inclusion_tag

    类似将html页面功能分块返回了~

    自定义inclusion_tag,my_tag.py

    from django import templateregister = template.Library()  # register的名字是固定的,不可改变@register.inclusion_tag(\'login.html\',name=\'my_inclusion\')def inclusion(n):l = []for i in range(1,n):l.append(f\'第{i}页\')return locals()  # 将当前名称空间所有名字返回给login.html

    views.py

    def func(request):return render(request, \'func.html\', locals())

    lit.py 中间html

    <ul>{% for foo in l %}<li>{{ foo}}</li>{% endfor %}</ul>

    func.html

    {#加载过滤器#}{% load my_tag %}{#生成10个li#}{% my_inclusion 10 %}

    模板继承

    模板可以用继承的方式来实现复用,减少冗余内容。

    网页的头部和尾部内容一般都是一致的,我们就可以通过模板继承来实现复用。

    父模板用于放置可重复利用的内容,子模板继承父模板的内容,并放置自己的内容。

    父模板

    标签 block…endblock: 父模板中的预留区域,该区域留给子模板填充差异性的内容,不同预留区域名字不能相同

    {% block 名称 %}预留给子模板的区域,可以设置设置默认内容{% endblock 名称 %}

    子模板

    子模板使用标签 extends 继承父模板:

    {% extends "父模板路径"%}

    子模板如果没有设置父模板预留区域的内容,则使用在父模板设置的默认内容,当然也可以都不设置,就为空。

    子模板设置父模板预留区域的内容:

    {% block 名称 %}子内容{% endblock 名称 %}

    子版也可以继续使用母版划定区域内的内容

    {{ block.super }}

    父模板如何划分区域

    划定区域的时候一般都应该有三个区域:CSS区域,HTML文档区域、JS区域

    这样划分区域提高了页面的可扩展性和方便维护等优点

    {% block css %}{% endblock %}{% block content %}{% endblock %}{% block js %}{% endblock %}
  • 赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » Django 模板