zoukankan      html  css  js  c++  java
  • Django 2.0 学习(12):Django 模板语法

    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>
    

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

    运行结果为

  • 相关阅读:
    重新想象 Windows 8 Store Apps (15) 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager
    重新想象 Windows 8 Store Apps (12) 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
    返璞归真 asp.net mvc (10) asp.net mvc 4.0 新特性之 Web API
    与众不同 windows phone (29) Communication(通信)之与 OData 服务通信
    与众不同 windows phone (33) Communication(通信)之源特定组播 SSM(Source Specific Multicast)
    与众不同 windows phone (27) Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
    与众不同 windows phone (30) Communication(通信)之基于 Socket TCP 开发一个多人聊天室
    返璞归真 asp.net mvc (12) asp.net mvc 4.0 新特性之移动特性
    重新想象 Windows 8 Store Apps (2) 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, RadioButton, CheckBox, ToggleSwitch
    重新想象 Windows 8 Store Apps (10) 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom
  • 原文地址:https://www.cnblogs.com/love9527/p/9077863.html
Copyright © 2011-2022 走看看