• 【转】Django 模板语法


    转自:https://www.cnblogs.com/love9527/p/9077863.html

    Django 模板语法

    一、模板

    只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。

    二、模板语法

    模板语法变量:{{ }}
    在Django模板中遍历复杂数据结构的关键是句点字符 .(其实就是点号)
    views.py

    from django.shortcuts import render
    
    
    def index(request):
        name = "Hello world!"
        number = 101
        lst = [1, 2, 3, 4, 5]
        dic = {"name": "eric", "job": "teacher"}
    
        class People:
            def __init__(self, name, age):
                self.name = name
                self.age = age
    
            def __str__(self):
                return self.name + str(self.age)
    
            def dream(self):
                return "你有梦想吗?"
    
        # 实例化
        person_jack = People("jack", 10)
        person_pony = People("pony", 36)
        person_cent = People("cent", 55)
        person_list = [person_jack, person_pony, person_cent]
    
        return render(request, "index.html",
                      {
                          "name": name,
                          "num": number,
                          "lst": lst,
                          "dic": dic,   # 键对应的是模板里的名字,值对应的是上面定义的值
                          "person_jack": person_jack,
                          "person_pony": person_pony,
                          "person_list": person_list
                      }
                      )

    templates/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Django 模板</title>
    </head>
    <body>
        <h3>变量{{ variable }}:深度查询</h3>
        <h5>{{ name }}</h5>
        <p>{{ num }}</p>
        <p>{{ lst }}</p>
        <p>{{ dic }}</p>
        <p>{{ lst.0 }}</p>
        <p>{{ lst.4 }}</p>
        <p>{{ dic.name }}</p>
        <p>{{ dic.job}}</p>
        <p>{{ person_jack.name }}</p>
        <p>{{ person_jack.age }}</p>
        <p>{{ person_list.2.name }}</p>
    </body>
    </html>

    运行输出结果如下图所示:

    注意:在使用templates时,需要在django项目的settings配置文件中对templates的路径做如下配:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            # os.path.join(BASE_DIR, "templates"),启用django模板;
            # 如果没有这句会出现"django.template.exceptions.TemplateDoesNotExist: index.html"错误
            'DIRS': [os.path.join(BASE_DIR, "templates")],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]

    其中,局点符也可以用来引用对象的方法(无参数方法)

    <h4>字典:{{ dic.name.upper }}</h4>

    模板语法标签:{% tag %}
    标签语法是:{% tag %},它比变量更加复杂:一些在输出中创建文本,一些通过循环或者逻辑来控制流程,一些加载其后的变量将使用道德额外信息到模板中。一些标签需要开始和结束标签(例如:{% tag %}... 标签内容...{% endtag %})。
    1.for标签(循环序号可以通过{{ forloop }}显示)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Django 模板</title>
    </head>
    <body>
        <h3>循环取值</h3><hr>
        {% for item in person_list %}
            <p>{{ item.name }}, {{ item.age }}</p>
        {% endfor %}
    
        <h3>循环取值:倒序</h3>
        {% for item in person_list reversed %}
            {# 序号从1开始 #}
            <p>{{ forloop.counter }}---------->{{ item.name }}, {{ item.age }}</p>
            {# 序号从0开始 #}
            <p>{{ forloop.counter0 }}---------->{{ item.name }}, {{ item.age }}</p>
            {# 序号倒序 #}
            <p>{{ forloop.revcounter }}---------->{{ item.name }}, {{ item.age }}</p>
        {% endfor %}
    
        <h3>循环取值:字典</h3>
        {% for key, value in dic.items %}
            <p>{{ key }}, {{ value }}</p>
        {% endfor %}
    </body>
    </html>

    运行结果如下图所示:

    2.for ... empty:for标签带有一个可选的{% empty %}从句,以便再给出的组是空的或者没有被找到时,可以有所操作

    {% for person in person_list %}
        <p>{{ person.name }}</p>
    {% empty %}
        <p>sorry,no this person</p>
    {% endfor %}

    3.if标签:{% if %}会对一个变量求值,如果它的值是"True"(存在、不为空且不是boolean类型的false值),对应的内容块被执行

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Django 模板</title>
    </head>
    <body>
        {% if num > 200 %}
            <p>大于</p>
        {% elif num == 200 %}
            <p>等于</p>
        {% else %}
            <p>小于</p>
        {% endif %}
    
    </body>
    </html>

    4.with:使用一个简单的名字还出一个复杂的变量,当我们需要一个"昂贵的"方法(比如:访问数据库)很多次的时候是非常有用的

    {% with total=business.emlpoyees.count %}
        {{ total }} empolyee {{ total | pluralize }}
    % endwith %}
    <p>{{ person_list.2.name }}</p>
    {% with name=person_list.2.name %}
        <p>{{ name }}</p>
    {% endwith %}

    5.csrf_token:跨站点请求伪造保护
    提交数据的时候会做安全机制,当用户点击提交的时候会出现一个forbidden错误,就是用settings配置里面的csrf做的安全机制,如果我们不需要使用,可以将其注释。或者在form表单下面添加{% csrf_token %}来解决该问题(这才是真正的解决办法,注释不是解决办法)。

    <h3>scrf_token</h3>
        <form action="/tag/" method="post">
            {% csrf_token %}
            <p><input type="text" name="haiyan"></p>
            <input type="submit">
        </form>

    模板语法过滤器:{{ obj|filter__name:param }},过滤器使用管道字符

    1.default:{{ variable| default: "nothing"}},如果变量是false或者为空,使用默认值。否则,使用变量的值

    <p>default过滤器:{{ li|default:"如果显示为空,设置解释性的内容。" }}</p>

    2.length:返回值的长度,它对字符串和列表都起作用

    {{ value | length }}        # 如果value是["a", "b", "c", "d"],那么输出是4

    3.filesizeformat:将值格式化为"人类可读"的文件尺寸(例如:13KB,4.1M,102bytes等等)

    {{ value | filesizeformat }}        # 如果value是123456789,输出将会是117.7MB

    4.date:格式化日期时间格式

    {{ value | date:"Y-m-d" }}        # 如果value=datetime.datetime.now(),返回时间的年-月-日格式

    5.slice:切片

    {{ value | slice:"2:-1" }}        # 如果value="hello world",返回'llo worl'

    6.truncatechars:截断
    如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(...)结尾,参数:要截断的字符数。

    <p>截断字符: {{ content | truncatechars:20 }}</p>
    <p>截断单词: {{ content | truncatewords:4 }}</p>

    如果content是"i am is jack, where are you come from?"
    输出结果:截断字符: i am is jack, whe...;截断单词i am is jack, where...

    7.safe
    django的模板中会对HTML标签和JS语法标签进行自动转义,这样是为了安全。但是有的时候我们不想这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章是经过修饰的,这些修饰可能是通过类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在django中关闭HTML自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器"|safe"的方式告诉django这段代码是安全的不必转义,如下:

    value="<a href="">点击</a>""
    
    {{ value | safe }}
    <p>{{ label }}</p>        # 为了安全,系统会把标签变成字符串
    <p>{{ label | safe }}</p>        # 加上safe,确定数据时安全的才能被当成是标签

    这里简单介绍常用的几个模板过滤器,更多内容请参考

    三、自定义标签和过滤器

    • 1.在app目录中创建templatetags包(包名只能是templatetags);

    • 2.在项目settings.py中把templatetags目录作为app注册;
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'polls.apps.PollsConfig',
        'polls.templatetags'        # 作为app注册
    ]
    • 3.在customtags.py文件中添加自定义的标签和过滤器
    from django import template
    
    register = template.Library()       # register的名字是固定的,不可改变
    
    
    @register.filter(name="cut")        # 过滤器在模板中使用时的name
    def custom_cut(value, arg):     # 将传递过来的参数arg替换为"#"
        return value.repalce(arg, "#")
    
    
    @register.tag(name="current_time")
    def current_time(parse, token):     # parse解析器对象,token被解析的对象,包含标签的名字和格式化的格式
        try:
            tag_name, format_string = token.split_contents()
        except:
            raise template.TemplateSyntaxError("syntax")
        return CurrentNode(format_string[1:-1])     # 传入模板中的节点类
    
    
    import datetime
    
    
    class CurrentNode(template.Node):
        def __init__(self, cus_format):
            self.format_string = str(cus_format)
        
        def render(self, context):
            now = datetime.datetime.now()
            return now.strftime(self.format_string)
    • 4.编辑视图函数,把value传递给模板文件:
    def index(request):
        return render(request, "one.html", {"value": "hello world!"})
    • 5.在模板文件中使用的时候需要先导入customtags.py文件:
    {% load customtags %}
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>自定义标签和过滤器</title>
    </head>
    <body>
        {{ value|cut:"!" }}<br>
        {% current_time "%Y-%m-%d %H:%M:%S" %}
    </body>
    </html>

    注意:在模板中不要随意添加空格,尤其是变量和标签

    运行结果为

  • 相关阅读:
    POJ 2456 Aggressive cows
    POJ 1064 Cable master
    POJ 3723 Conscription
    左偏树
    tarjan模板
    [bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑
    [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列
    [bzoj3218]a + b Problem 网络流+主席树优化建图
    #6034. 「雅礼集训 2017 Day2」线段游戏 李超树
    【UOJ UNR #1】火车管理 可持久化线段树
  • 原文地址:https://www.cnblogs.com/yoyo008/p/10855791.html
Copyright © 2020-2023  润新知