Five, Django's template rendering and inheritance

Django's template rendering, inheritance

First, grammar

Two special symbols:

{{ }} with{% %}

{{}} Variable with the logic associated with a logical {%}% related variables.

Second, variable

Click Django template language syntax used in: {{variable name}}

When the template engine encounters a variable, it will calculate the variable, and then replace it with the result itself. Named variables include any alphanumeric and underscore ( "_") combination. Variable names can not contain spaces or punctuation

urls.py 先配置路径:
    url(r'^index/', views.index),
    
views.py 
    from django.shortcuts import render,HttpResponse,redirect
    
    def index(request):
        num = 100
        name = 'alex'
        food_list = ['蒸熊掌','烧花鸭','烧子鹅']
        dic = {'year':2019,'month':7,'day':17}

        class Animal:
            def __init__(self):
                self.kind = 'dog'
            def color(self):
                return 'black'
        a = Animal()

        return render(request,'index.html',{'num':num,'name':name,'food_list':food_list,'dic':dic,'a':a})
        # 通过字典的形式传把值给html文件
        return render(request,'index.html',locals())
        # locals() 获取函数内部所有变量的值,并加工成{'变量名':'变量值'....}这样一个字典

index.html
    <p>{{ num }}</p>
    <p>{{ name }}</p>
    <p>{{ food_list }}</p>
    <p>{{ dic }}</p>
    <p>{{ a }}</p>
    <p>{{ a.kind }}</p>
    <p>{{ a.color }}</p>

note:

  • views: For about locals () This method can obtain the value of all variables of the internal function, the easy way, it can be used, but many unwanted variables are transmitted into, inefficiency
  • html in: call the object inside the method when the brackets do not need to write to execute; and can only execute method does not pass parameters if this method requires transmission parameters, so the template language is not supported, you can not help rendering

Third, the filter

In Django template language by using filters to change the display of variables.

The syntax of the filter: {{value | method name: Parameter}} use the pipe "|" of applying a filter, a colon ":" to the connection parameters

Django template language provides about sixty built-in filter

length

获取数据长度,没参数,作用于字符串和列表   {{ value|length }} 

<p>{{ food_list|length }}</p>

default

默认值,有参数,如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值

<p>{{ xx|default:'啥也没有' }}</p>  # views若没有传过来xx的值,所以就会显示设置的默认值

filesizeformat

将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)

# 比如在views中  size = 123456 
<p>{{ size|filesizeformat }}</p>  # 此时格式转换成  120.6 KB

slice

切片 ,跟字符串、列表的切片方法一样   {{value|slice:"2:-1"}}

<p>{{ name|slice:':3' }}</p>  # 0可省略

date

时间格式化显示

# 比如在views中  ntime = datetime.datetime.now()
<p>{{ ntime|date }}</p>                # July 17, 2019
<p>{{ ntime|date:"Y-m-d H:i:s"}}</p>   # 2019-07-17 16:27:55

truncatechars

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

# 比如在views中  name = 'alexdsb'
<p>{{ name|truncatechars:7 }}</p>    # alex...
#注意:最后那三个省略号也是7个字符里面的,也就是这个7截断出来的是4个字符+3个省略号

truncatewords

单词截断  在一定数量的字后截断字符串,是截多少个单词 

# 比如在views中  word = 'hello girl hi baby yue ma'
<p>{{ word|truncatewords:4 }}</p>  # hello girl hi baby ...
# 单词截断,截的是多少个单词,省略号不算

cut

移除value中所有的与给出的变量相同的字符串  

# 比如在views中  word = 'hello girl hi baby yue ma'
<p>{{ words|cut:'i' }}</p>   # hello grl h baby yue ma

join

使用字符串连接列表,{{ list|join:', ' }},就像Python的str.join(list)  

# 比如在views中  food_list = ['蒸熊掌','烧花鸭','烧子鹅']
<p>{{ food_list|join:'+' }}</p>   # 蒸熊掌+烧花鸭+烧子鹅

safe

将 字符串识别成标签  

If I wrote a js code in a user's comments when, if not escape, js code will execute, and the browser will pop up and so on, this is called xss attack. Django templates during template rendering time, for safety, would HTML tags such as grammar and JS tags automatically escaped. Turn off automatic HTML in Django escaped in two ways, if it is a single variable that we can pass through the filter "| safe" way to tell Django code does not have to be a safe escape.

# 比如在views中  tag = '<a href="http://www.baidu.com">百度</a>'

<p>{{ tag }}</p>      # <a href="http://www.baidu.com">百度</a> 只会当成字符串
<p>{{ tag|safe }}</p> # 显示了一个百度的a标签

Fourth, label Tags

Tag looks like this: {% tag%}

Or to control flow through the logic loop, some variables followed by loading the additional information to the template.

Some tags require the start and end tags (e.g. {% tag%} ... Tag Content ... {% endtag%}).

The for loop label

Common methods for loop

循环一个字典:

views
    dic = {'year':2019,'month':7,'day':17}
html
    {% for key,value in dic.items %}
        <li>{{ key }} -- {{ value }}</li>
    {% endfor %}
   

循环一个列表:
views
    food_list = ['蒸熊掌','烧花鸭','烧子鹅']
html
    <ul>
        {% for food in food_list %}
            <li>{{ food }}</li>
        {% endfor %}
    </ul>
    
    # 利用 reversed 反向完成循环
    <ul>
        {% for food in food_list reversed %}
            <li>{{ food }}</li>
        {% endfor %}
    </ul>

Other methods for recycling

forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0           当前循环的索引值(从0开始)
forloop.revcounter         当前循环的倒序索引值(从1开始)
forloop.revcounter0        当前循环的倒序索引值(从0开始)
forloop.first              当前循环是不是第一次循环(布尔值)
forloop.last               当前循环是不是最后一次循环(布尔值)
forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等,比如:forloop.parentloop.counter

Note: cycle number can display {{forloop}}, must be used inside the loop 

{% for key,value in dic.items %}
    {{ forloop.counter }}             # 从1开始计数,比如dic有3个键值对,就1,2,3
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}

{% for key,value in dic.items %}
    {{ forloop.counter0 }}             # 从0开始计数,比如dic有3个键值对,就0,1,2
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}

{% for key,value in dic.items %}
    {{ forloop.revcounter }}            # 倒序直到1计数,比如dic有3个键值对,就3,2,1
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}

{% for key,value in dic.items %}
    {{ forloop.revcounter0 }}            # 倒序直到0计数,比如dic有3个键值对,就2,1,0
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}

{% for key,value in dic.items %}
    {{ forloop.first }}                  # 判断是不是第一次循环,显示bool值
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}

{% for key,value in dic.items %}
    {{ forloop.last }}                    # 判断是不是第一次循环,显示bool值
    <li>{{ key }} -- {{ value }}</li>
{% endfor %}


forloop.parentloop示例:
循环views中的列表  d1 = [['春天','夏天','秋天','冬天'],['雨水','清明']]

{% for dd1 in d1 %}
    {% for ddd1 in dd1 %}
        {{ forloop.parentloop.counter }}
        {{ forloop.counter }}
        <div>{{ ddd1 }}</div>
    {% endfor %}
{% endfor %}

1 1  父辈的循环计数是1,自己的循环计数是1
春天
1 2  父辈的循环计数是1,自己的循环计数是2
夏天
1 3  父辈的循环计数是1,自己的循环计数是3
秋天
1 4  父辈的循环计数是1,自己的循环计数是4
冬天
2 1  父辈的循环计数是2,自己的循环计数是1
雨水
2 2  父辈的循环计数是2,自己的循环计数是2
清明

for .... empty

for a label with optional {% empty%} clause set forth in order to empty or is not found, the operation may be.

比如在views中并没有给出 person_list,此时html中

{% for person in person_list %}
    <p>{{ person.name }}</p>

{% empty %}
    <p>sorry,no person here</p>
{% endfor %}

因为没有找到这个列表,页面就会显示empty中的内容 sorry,no person here

如果有  person_list = [{'name':'dazhuang'},{'name':'taibai'},{'name':'alex'}]
此时页面就会显示:dazhuang、taibai、alex

if the label

if statement supports and, or, ==,>, <,! =, <=,> =, in, not in, is, is not to judge, pay attention to the conditions on both sides spaces

note:

  • Django template language does not support continuous determination, i.e., does not support the following wording:
    {% IF A> B> C%}
    ...
    {%} endif%
  • Having a higher priority process attribute Django template language (Learn)
    DEF XX (Request):
    D = { "A":. 1, "B": 2, "C":. 3, "items": "100"}
    return render (request, "xx.html", { "data": d})
    described above, when we use a render method to render a page, a pass key is the dictionary items d and also default d.items () a method, in case the template language: {{data.items}}, by default, takes the d values key items, key items take a value corresponding to 100 d, i.e., rather than executing the items method

    {% if num > 100 or num < 0 %}

    What the hell


    {% elif num >= 80 and num <= 100 %}

    Gangster really fierce


    {% else %}

    Minato live it


    {% endif %}

    If the views pass over num = 100, the page display big brother woolly

with label

Use a simple name cache a complex variable, used to a complex variable aliases, note no space around the equal sign

假如views中有这样一个列表 person_list = [{'name':'dazhuang'},{'name':'taibai'},{'name':'alex'}],我想把 alex 取出来

两种方式:
    方式一:
        {% with name=person_list.2.name %}  # 注意等号两边没有空格
            {{ name }}        # 只能在with语句体内用,外边就不好使了
        {% endwith %}
    方式二:
        {% with person_list.2.name as name %}
            {{ name }}
        {% endwith %}

csrf_token label

当以post提交表单的时候,会报错,我们之前的解决办法是在settings里面的中间件配置里面把一个csrf的防御机制给注销了 ,而本身是不应该注销的,不让自己的操作被forbiden,通过csrf_token标签就能搞定。

这个标签用于跨站请求伪造保护  

在页面的form表单里面(注意是在form表单里面)任何位置写上{% csrf_token %},这个东西模板渲染的时候替换成了<input type="hidden" name="csrfmiddlewaretoken" value="8J4z1wiUEXt0gJSN59dLMnktrXFW0hv7m4d40Mtl37D7vJZfrxLir9L3jSTDjtG8">,隐藏的,这个标签的值是个随机字符串,提交的时候,这个东西也被提交了,首先这个东西是我们后端渲染的时候给页面加上的,那么当你通过我给你的form表单提交数据的时候,你带着这个内容我就认识你,不带着,我就禁止你,因为后台我们django也存着这个东西,和你这个值相同的一个值,可以做对应验证是不是我给你的token,就像一个我们后台给这个用户的一个通行证,如果你用户没有按照我给你的这个正常的页面来post提交表单数据,或者说你没有先去请求我这个登陆页面,而是直接模拟请求来提交数据,那么我就能知道,你这个请求是非法的。

such as:

views:
    def index(request):
    if request.method == 'GET':
        return render(request,'index.html')
    else:
        return HttpResponse('成功了呢!!!')
    
index.html:
    <form action="" method="post"> 
        内容:<input type="text">
        <button>提交</button>
    </form>
    
# 此时,我们没有加{% csrf_token %},也没注销settings里的防御机制,则网页会报错操作被forbiden

Plus try {% csrf_token%}:

views:
    def index(request):
    if request.method == 'GET':
        return render(request,'index.html')
    else:
        return HttpResponse('成功了呢!!!')
    
index.html:
    <form action="" method="post"> 
        {% csrf_token %}
        内容:<input type="text">
        <button>提交</button>
    </form>
    
# 此时,我们就可以正常的拿到post请求后执行的页面了

Fifth, template inheritance

语法: {% extends 'base.html' %} ,可预留钩子block

模版继承就是创建一个基本的“骨架”模版,它包含站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。

当我们写许多网页的时候,发现部分网页里面的许多内容都很类似,这样我们就把相似的内容都拿出来,制作成一个母版,需要的页面来继承,这样就会节省许多的重复代码。 



制作这样一个界面,输入127.0.0.1:8000/home/,访问首页,显示右边内容是home页面;点击菜单1时,跳转到menu1界面,右边显示menu1;菜单2和3同理;
  1. Configure the path urls:
    from django.conf.urls Import url
    from app01 Import views

    urlpatterns = [
        url(r'^home/', views.home),
        url(r'^menu1/', views.menu1),
        url(r'^menu2/', views.menu2),
        url(r'^menu3/', views.menu3),
    ]
    Home configured path home /, and three menu path
  2. View function views:
    from the render django.shortcuts Import

    def home(request):
        return render(request,'home.html')
    
    def menu1(request):
        return render(request, 'menu1.html')
    
    def menu2(request):
        return render(request, 'menu2.html')
    
    def menu3(request):
        return render(request, 'menu3.html')
    Write view functions and three menu Home
  3. We need to build four html file: html a home page home.html, and three menu
    when we do not inherit the template method, because the navigation bar and menu bar are the same four documents, so the code four files most, like so much of the repetition code
    with home home, for example, the same three basic menu

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="utf-8">
        <title>模板继承</title>
        <style>
            body{
                margin: 0;
                padding: 0;
            }
            .nav{
                background-color: black;
                height: 40px;
                line-height: 40px;
            }
            .nav a{
                color: white;
                text-decoration: none;
                padding: 0 50px;
            }
            .left-menu{
                background-color: gray;
                color: white;
                height: 600px;
                width: 20%;
                float: left;
            }
            .left-menu a{
                color: white;
                text-decoration: none;
            }
            ul{
                margin: 0;
                padding: 0;
            }
            li{
                padding-left: 75px;
                height: 50px;
                line-height: 50px;
                border: 1px solid black;
            }
            .content{
                width: 80%;
                float: right;
            }
            .clearfix{
                content: '';
                display: block;
                clear: both;
            }
        </style>
    
    
    </head>
    <body>
    
    <div class="nav">
        <a href="">外设首页</a>
        <a href="">鼠标专卖</a>
        <a href="">键盘专卖</a>
        <a href="">耳麦专卖</a>
        <input type="text"><button>搜索</button>
    </div>
    <div class="clearfix">
        <div class="left-menu">
            <ul type="none">
                <li><a href="/menu1/">菜单1</a></li>
                <li><a href="/menu2/">菜单2</a></li>
                <li><a href="/menu3/">菜单3</a></li>
            </ul>
        </div>
        <div class="content">
            home页面             只需要改这里,改成其他三个菜单对应的内容
        </div>
    </div>
    
    </body>
    </html>
  4. Template inheritance to finish
    first create a master file base.html, to put the same content
    <! DOCTYPE html>



    模板继承

    </head>
    <body>
    
    <div class="nav">
        <a href="">外设首页</a>
        <a href="">鼠标专卖</a>
        <a href="">键盘专卖</a>
        <a href="">耳麦专卖</a>
        <input type="text"><button>搜索</button>
    </div>
    <div class="clearfix">
        <div class="left-menu">
            <ul type="none">
                <li><a href="/menu1/">菜单1</a></li>
                <li><a href="/menu2/">菜单2</a></li>
                <li><a href="/menu3/">菜单3</a></li>
            </ul>
        </div>
        <div class="content">
            {% block content %}         这就是钩子
                母版页面
            {% endblock content %}
        </div>
    </div>
    
    </body>
    </html>

    Home home.html (html file three additional menu of empathy):
    {% the extends 'base.html'%} inheritance syntax

    {% block content %}           钩子,写自己的的内容,去替换母版钩子的内容
        首页页面
    {% endblock content %}

    Thus the same effects can be completed prior to, and saves a lot of code

Note specific point:

  • Use {% extends%} tags in the template, it must be the first tag in the template. Under any other circumstances, template inheritance will not work, when rendering templates django do not know what you're doing
  • The more template provided in the base {% block%} tag as possible (typically defining at least three hooks, html pages a, css a, js a), the parent of all necessary to define sub-template in the template Blocks, so that you can filling reasonable default content in most blocks, and then, only the definition that you need a
  • The content and sub-pages inherit master the contents inside the block while retaining
    {% block title%}
    {{}} # block.super master display the contents of
    xxx # display your content
    {% endblock title%}
  • For better readability, you can also give your {% endblock%} tag name
    {% Block title%}
    xxx
    {% endblock%} title
  • A plurality of the same name can not be defined in a block tag template.

Six components

Syntax: {% include 'navbar.html'%}

The page content may be used, such as navigation, footer information components stored in a separate file and then use where needed, can be introduced anywhere in the file by the following syntax.

For example: There nav.html file navigation bar

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c1{
            background-color: red;
            height: 40px;
        }
    </style>
</head>
<body>

<div class="c1">
    <div>
        <a href="">xx</a>
        <a href="">dd</a>
    </div>
</div>

</body>
</html>

At this point there is a test.html file, embedded directly in the page above the navigation bar

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% include 'nav.html' %}      组件的语法
<h1>xxxxxxxxxx</h1>
</body>
</html>

Such test.html file does not have to write code navigation bar, but still got the navigation bar

The difference between simple components and plug-ins

组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等。

而插件更倾向封闭某一功能方法的函数。

这两者的区别在 Javascript 里区别很小,组件这个名词用得不多,一般统称插件。

Seven, custom tags and filters

Custom filter

  1. Create a folder in the app templatetags application file, folder must be the name
  2. templatetags file to create a xx.py file, the name of the file can be free to play, such as call my_tags.py
  3. Creating custom filters in my_tags.py files
    from django import template # first import the template

    register = template.Library()    # register相当于一个注册器,名字是固定的,不可改变
    
    @register.filter       # 这样使用注册器,注意filter后不加括号
    def my_filter(v1):     # 不带参数的过滤器
        s = v1 + '你真好' 
        return s
    
    @register.filter       # 这样使用注册器,注意filter后不加括号
    def my_filter(v1,v2):  # 带参数的过滤器(最多传递一个参数)
        s = v1 + '你真好' + v2
        return s
  4. urls configured paths, views written view function
    urls:
    URL (R & lt 'index ^ /', views.index),

    views:
        def index(request):
         name = 'alex'
         return render(request,'test.html',{'name':name})
  5. Test.html file created in the template file templates, you can use by introducing
    {% the Load my_tags%}
    {{name | My_Filter}} page displays: alex nice of you

    {% load my_tags %}
    {{ name|my_filter:'呵呵' }}    页面显示:alex你真好呵呵
  6. Note: Since the filter can only be passed up to a defined parameter, multiple parameters may be considered custom labels

Custom label

  1. Templatetags still is to create a folder in the app, create a file in the file xx.py
  2. Create custom labels:
    @ register.simple_tag
    DEF my_tag (V1, V2, V3): # can pass a plurality of parameters
    s = v1 + 'like' + V2 + V3
    return S
  3. Html file using custom tags:
    {% my_tag name 'barbecue' 'Ha beer'%} page displays: alex like to eat barbecue Ha beer

inclusion_tag

Used for return html snippet can be a html file the first template rendering, rendering finished, the html file as a component, into the place where you use this tag

  1. Templatetags still is to create a folder in the app, create a file in the file xx.py
  2. Create a custom inclusion_tag
    @ register.inclusion_tag ( 'test02.html')
    DEF FUNC (v1):

        return {'data':v1}  此时v1接收的 l1 = [11,22,33]
    func of return data passed test02.html, as a template to render data after test02.htm will render good as a unit, to generate call this place the func
  3. Establishing test02.html, encapsulating some of the features, components corresponding to


      {% for d in data %}
    • {{ d }}

    • {% endfor %}

    At this time, go another html file can be similar to the component referenced pages test02 introduced in, for example, in the test.html:
    {my_tag% Load%}
    {%}% FUNC L1 L1 is passed over the function views , but this time passed to func

Eight static configuration file

js, css, img and so is called a static file, then the configuration on django static files, we need to configure some settings in the configuration file contents inside

  1. Create a folder dedicated to put static files in the folder of the project, such as call jingtaiwenjian
  2. In the configuration settings:
    STATIC_URL = '/ static /' # alias specified path

    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'jingtaiwenjian'),
    ]
  3. Call static file:
    in the html file, want to join a css styles, there is a method to introduce static files:

    方式一:
     <link rel="stylesheet" href="/jingtaiwenjian/mycss.css">  这样写是不对的,要用别名static
     <link rel="stylesheet" href="/static/mycss.css">
    
    方式二:
     {% load static %}
     <link rel="stylesheet" href="{% static 'mycss.css' %}">
    
    方式三:
     <link rel="stylesheet" href="{% get_static_prefix %}mycss.css">
    Alias ​​static advantages:
    • Alias ​​is also a safety mechanism on the browser via the commissioning stage you can see is the alias name, so that others can not know the name of the folder you static, improves security, or else someone else will be able through this folder path attack.
    • If when maintenance updates and changed the name of the static folder, because the use of aliases, so it will not affect the improved scalability
    • Even if the alias may also modify, use the time to find a path through the alias load static, to obtain a static file path by way of an alias mapping

{% static %}

引入一张图片:    
    {% load static %}
    <img src="{% static "images/hi.jpg" %}" alt="Hi!" />
    
引用JS文件时使用:
    {% load static %}
    <script src="{% static "mytest.js" %}"></script>
    
某个文件多处被用到可以存为一个变量
    {% load static %}
    {% static "images/hi.jpg" as myphoto %}
    <img src="{{ myphoto }}"></img>

{% Get_static_prefix%} alias acquired prefix

{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者,用别名:
{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

Guess you like

Origin www.cnblogs.com/yangzm/p/11209966.html