欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

django之模板层

程序员文章站 2022-05-18 20:58:28
[TOC] 模板语法 两种书写格式: 变量相关 {{ }} 逻辑相关 {% %} 模板传值 给html页面传值的两种方式 第一种方式 弊端就是:当要传的变量名很多的时候,就很麻烦 第二种 locals() locals() 会将当前所在的名称空间中所有的名字全部传递给html页面 传值 基本数据类型 ......

目录

模板语法

两种书写格式:

  • 变量相关 {{ }}
  • 逻辑相关 {% %}

模板传值

给html页面传值的两种方式

第一种方式

def test(request):
    n = 1
    f = 1.21
    s = 'hellow world'
    lt = [11, 22, 33, 44, 55, 66]
    tu = (111, 222, 333)
    dic = {'username': 'neo', 'password': '123'}
    se = {1, 3, 5, 7, 9}
    bo = true

    return render(request, 'test.html', 'n': n, 'dic': dic)

弊端就是:当要传的变量名很多的时候,就很麻烦

第二种 locals()

locals() 会将当前所在的名称空间中所有的名字全部传递给html页面

传值 基本数据类型

def test(request):
    n = 1
    f = 1.21
    s = 'hellow world'
    lt = [11, 22, 33, 44, 55, 66]
    tu = (111, 222, 333)
    dic = {'username': 'neo', 'password': '123'}
    se = {1, 3, 5, 7, 9}
    bo = true

    return render(request, 'test.html', locals())

前端接收:

<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ lt }}</p>
<p>{{ tu }}</p>
<p>{{ s }}</p>
<p>{{ se }}</p>
<p>{{ bo }}</p>
<p>{{ dic }}</p>

传函数名

def test(request):
    def func1():
        pass
    
    return render(request, 'test.html', locals())

前端

<p>传函数名 {{ func1 }}</p>

显示效果:传函数名 none

注意:

  • 给html页面传递函数名的时候,模板语法会自动加括号调用该函数,并且将函数的返回值显示在浏览器页面上

  • 但是模板语法不支持函数传参,意味着给html页面传的函数只能是不需要传参数调用的函数。

传类名和对象

    def func1():
        pass


    class myclass(object):
        def get_self(self):
            return 'get_self'

        @classmethod
        def get_cls(cls):
            return 'get_cls'

        @staticmethod
        def get_func():
            return 'get_func'

    obj = myclass()

前端:

<p>传类名:{{ myclass }}</p>
<p>传对象名: {{ obj }}</p>

<p>{{ obj.get_cls }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.get_func }}</p>

总结:只要是能够加括号调用的 传递到html页面上都会自动加括号调用

过滤器

语法结构

|来使用, 会自动将 | 左边的数据当作过滤器的第一个参数传入, :右边的当作第二个参数

<p>统计长度:{{ s|length }}</p>

常用的方法

  • 统计长度<p>统计长度:{{ s|length }}</p>, 如果无法统计长度会默认返回0
  • 加法运算:{{ n|add:666 }}, 内部异常捕获 支持数字相加 字符串拼接 都不符合返回空
  • 切片操作:{{ lt|slice:'0:5:2' }}, 顾头不顾尾 也支持步长
  • 自动转成文件大小格式{{ file_size|filesizeformat }}
  • 截取文本内容:s|truncatechars:5 (按字符计算)截取五个字符,三个点也算
  • 截取文本内容:{{ s1|truncatewords:5 }}, (按照空格计算) 截取五个单词 三个点不算
  • 判断是否有值:{{ is_value|default:'is_value变量名指向的值为空' }}, 有值展示值本身 没值展示默认值
  • 展示带有标签的文本{{ sss }}
    • 默认情况下 是不会自动转换成前端html标签,防止恶意攻击

前后端取消转义

前端:<p>{{ sss|safe}}</p> 这样就可以自动转换成前端html标签

后端:

from django.utils.safestring import mark_safe

def test(request):
    sss2 = "<h2>h2标签</h2>"
    res = mark_safe(sss2)
    
    return render(request, 'test.html', locals())


# 前端传res就行了

也就意味着 html代码可以不在html文件内写,可以在后端写完了传给前端

标签

逻辑相关的语法

for循环:

<p>标签  逻辑相关</p>
{% for foo in lt %}
    <p>{{ forloop }}</p>
    <p>{{ foo }}</p>
{% endfor %}

forloop 内置的对象:

{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': true, 'last': false}

django之模板层

if判断

{% if s %}
<p>s有值</p>
    {% else %}
    <p>s没有值</p>
{% endif %}

for循环和if判断联合使用

{% for foo in lt %}
    {% if forloop.first %}
        <p>第一次</p>
    {% elif forloop.last %}
        <p>最后一次</p>
    {% else %}
        <p>{{ foo }}有点意思</p>

    {% endif %}
{% endfor %}
{% empty %}
<p>当for循环的对象是空的时候会走 </p>

with起别名

后端有个大字典,传到前端:

comp_dic = {'username':'123', 'hobby':['study', 'run', ['rap', {'age':20}]]}

前端: <p>{{ comp_dic.hobby.2.1.age }}</p>

注意:模板语法的取值 只有一种方式 统一采用句点符

<p>当你的数据是通过多个句点符获取到的,后续又需要经常使用,可以给该数据起别名,但别名只能在with内部使用</p>
{% with comp_dic.hobby.2.1.age as age %}
    <p>{{ age }}</p>

{% endwith %}

自定义过滤器和标签

django支持用户自定义过滤器和标签

有三个步骤:

  • 在应用名下新建一个名字必须叫做templatetags的文件夹

  • 在该文件夹内,新建一个任意名称的py文件

  • 在该py文件中,必须先写下面两句代码

    from django.template import library
    
    register = library()

之后就可以用register自定义过滤器和标签了

自定义过滤器

和默认的过滤器一样 最多只能接受两个参数

from django.template import library

register = library()

# 自定义过滤器
@register.filter(name='neo')
def index(a, b):
    return a + b    # 两个数的和

需要先在html页面上 加载

{% load mytag %}
{{ 1|neo:2 }}

自定义的过滤器可以在逻辑语句中使用,而自定义的标签不可以

{% load mytag %}
{% if 1|neo:2 %}
    <p>有值</p>
    {% else %}
    <p>没有值</p>

{% endif %}

自定义标签

可以接收任意多个参数,参数与参数之间必须空格隔开

from django.template import library

register = library()

@register.simple_tag(name='mytag')
def mytag(a,b,c,d):
    return '%s*%s*%s*%s' % (a,b,c,d)   # 接收四个参数用*拼接

自定义inclusion_tag

是一个函数,能够接收外界传入的参数,然后传递给一个页面,页面上获取数据,渲染完成之后,将渲染好的页面放到调用inclusion_tag的地方。

mytag.py

from django.template import library

register = library()
@register.inclusion_tag('mytag.html', name='xxx')
def func(n):
    lt = []
    for i in range(n):
        lt.append(f'第{i}项')

    return locals()   # 将lt直接传递给mytag页面

template文件夹下mytag.html

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

</ul>

views.py返回的test.html页面

{% load  mytag %}
{% xxx 5 %}

注意: 当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag

模板的继承

继承模板extends

在子页面中在页面最上方使用下面的语法来继承母板

{% extends 'home.html' %}

块(block)

在父页面上利用block划定想要修改的区域,继承后就可以通过名字找到对应的名字找到该区域,并修改

  1. 模板上的block区域越多,页面的扩展性越强,推荐你一个模板页面至少有三块区域(css区域,html代码区域,js区域)
  2. 通过这三个区域,就能够实现每一个页面都有自己独立的css和js代码
  3. 可以在子页面上通过{{ block.super }}沿用父页面的内容

导入(include)

将html页面当做模块的直接导入使用:{% include 'form.html'%}

{% block content %}
    <p>我改成home1页面内容</p>
    {{block.super}}
    {% include 'form.html' %}
{% endblock %}

{% block css %}
    <style>
        p {
            color: green;
        }
    </style>
{% endblock %}

{% block js %}
    <script>
        alert('login')
    </script>
{% endblock %}