3.Django模板(Template)

常用语法·

{{ }} 和 {% %}

变量相关的用{{ }},逻辑相关的用{%%}。

模板渲染的官方文档

view中的代码

def template_test(request):
    l = [11, 22, 33] #列表
    d = {"name": "alex"} #字典

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age

        def dream(self):
            return "{} is dream...".format(self.name)

    Alex = Person(name="Alex", age=34) #自定义类对象
    Egon = Person(name="Egon", age=9000)
    Eva_J = Person(name="Eva_J", age=18)

    person_list = [Alex, Egon, Eva_J]
    return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

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

locals() 获取函数内容所有变量,然后通过reader方法给了template_test.html文件进行模板渲染,省事就可以用,但效率低

模板支持的写法

{# 取l中的第一个参数 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取对象的name属性 #}
{{ person_list.0.name }}
{# .操作只能调用不带参数的方法 #}
{{ person_list.0.dream }}

过滤器

在Django的模板语言中,通过使用 过滤器 来改变变量的显示。

  过滤器的语法: {{ value|filter_name:参数 }}

  使用管道符"|"来应用过滤器。

  例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。

  注意事项:

  1. 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
  2. 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
  3. 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
  4. '|'左右没有空格,有空格不显示效果

Django的模板大约有60个内置过滤器

filters

语法{{value|filter_name:参数}}

default

如果value值没传的话就显示nothing

{{ value|default: "nothing"}}

length

返回value的长度

{{ value|length }} 注:‘|’左右没有空格

filesizefomat

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

{{ value|filesizeformat }}

slice

切片,对字符串进行切片

{{value|slice:"2:-1"}}

date

格式化,如value = datatime.datetime.now()

{{ value|date:"Y-m-d H:i:s"}}

safe

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

{{ value|safe}}

truncatechars 

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

参数:截断的字符数

{{ value|truncatechars:9}} #三个省略号也包括在内

truncatewords

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

如 ''I Iove you , my girl I''

{{value|truncatewords:3}} #上面例子结果 ''I Iove you...'

cut

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

{{value|cut:' '}} #移除空行

jion

使用字符串连接列表

{{value|join:','}} #跟python的str.join很像

自定义filter

自定义过滤器只是带有一个或两个参数的Python函数:变量跟参数值

在app01目录下创建templateags文件夹,然后在文件夹中自定义app01_filters.py文件(文件名自定义)

编写自定义filter

from django import template
register = template.Library()

# 告诉Django的模板语言我现在有一个自定义的filter方法,名字叫sb
@register.filter(name="sb")
def add_sb(arg):
    return "{} sb.".format(arg)

# 告诉Django的模板语言我现在有一个自定义的filter方法,名字叫addstr
@register.filter(name="addstr")
def add_str(arg, arg2):
    """
    第一个参数永远是管道符前面那个变量
    :param arg: 道符前面那个变量
    :param arg2: 冒号后面的变量
    :return:
    """
    return "{} {}.".format(arg, arg2)

使用自定义filter

{# 先导入我们自定义filter那个文件 #}
{% load app01_filters %}

{# 使用我们自定义的filter #}
{{ somevariable|cut:"0" }}
{{ d.name|addstr }}

Tags标签

标签看起来像是这样的: {% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。一些标签需要开始和结束标签 (例如{% tag %} ...标签 内容 ... {% endtag %})。

for标签

遍历每一个元素:  写个for,然后 tab键自动生成for循环的结构,循环很基础,就这么简单的用,没有什么break之类的,复杂一些的功能,你要通过js

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% endfor %}
</ul>

变量字典

{% for key,val in dic.items %}
    <p>{{key}}:{{val}}</p>
{% endfor %}

其他循环号

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

for ... empty

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

<ul>
{% for user in user_list %}
    <li>{{ user.name }}</li>
{% empty %}
    <li>空空如也</li>
{% endfor %}
</ul>

if标签

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。

if,elif,else

{% if p3 %}
    <p>p3:{{ p3 }}</p>
{% elif p2 %}
    <p>p2:{{ p2 }}</p>
{% else %}
    <p>什么人都没有!</p>
{% endif %}

if else

{% if name_list|length >= 3 %}
    <p>需要打两辆车</p>
{% else %}
    <p>一辆足矣!</p>
{% endif %}

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。 

with

使用一个简单地名字缓存一个复杂的变量,多用于给一个复杂的变量起别名,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的

<p>with语句</p>
{{ name_list2.1.1 }}

{% with name=name_list2.1.1 %}
    {{ name }}
{% endwith %}

或者

{% with name_list2.1.1 as name %}

{{ name }}

{% endwith %}

csrf_token

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

注意是在form表单里面

在页面的form表单里面写上{% csrf_token %}

爬虫发送post请求模拟

import requests

res = requests.post('http://127.0.0.1:8000/login/',data={
    'username':'qian',
    'password':'123'
})

print(res.text)

注释

{# ... #}

注意事项

 Django的模板语言不支持连续判断,即不支持以下写法:

{% if a > b > c %}
...
{% endif %}

如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:默认会取d的items key的值。  

{{ data.items }}

模板继承  

       Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}
        母板的title信息
           {% endblock %}
    </title>
    <style>
        body{
            padding:0;
            margin: 0;
        }
        .nav{
            background-color:red;
            height: 40px;
        }
        .left_list div{
            width: 100px;
            height: 20px;
            background-color:pink;
            border-bottom:1px solid black;
        }
        .left_list{
            float:left;
            width: 100px;
        }
        .content{
            float:right;
            width:600px;
            height:100px;
        }
    </style>
</head>
<body>
<div class="nav"><a href="">新闻</a><a href="">视频</a><a href="">图片</a></div>

<div class="left_list">
    {% block list %}
    <div><a href="/index/">首页</a></div>
    <div><a href="/order/">订单页</a></div>
    <div><a href="/user/">个人中心</a></div>
    {% endblock %}

</div>
<div class="content">
    {% block content %}
      模板预留的地方
    {% endblock %}
</div>
</body>
</html>

 这个模版,我们把它叫作 base.html, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。

  在这个例子中, block 标签定义了三个可以被子模版内容填充的block。 block 告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。

  子模版index.html可能看起来是这样的:

{% extends 'base.html' %}
{% block title %}
首页
{% endblock %}
{% block content %}
    <a href="">首页</a>
    <span>首页介绍</span>
    {{ block.super }} #继承父类的模板内容
{% endblock %}

extends 标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。

  1. block标签中的名字是自己起的
  2. 不能在一个模版中定义多个相同名字的 block 标签

组件

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。

{% include 'nav.index' %}

 导航栏 nav.html

<!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="">alex</a>
        <a href="">wusir</a>
    </div>
</div>

</body>
</html>

嵌入导航栏页面 test.hrml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% include 'nav.html' %}
<h1>哈喽</h1>
</body>
</html>

自定义标签和过滤器

在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

在app中创建templatetags模块(模块名只能是templatetags)

创建任意 .py 文件,如:my_tags.py

from django import template
from django.utils.safestring import mark_safe

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


@register.filter
def filter_multi(v1, v2):
    return v1.replace('o', v2)


@register.simple_tag  # 和自定义filter类似,只不过接收更灵活的参数,没有个数限制。
def simple_tag_multi(v1, v2):
    return v1 * v2

在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

{% load my_tags %} 

home.html

{% load my_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{ date|date:'Y-m-d' }}
{{ name|filter_multi:'xxx'}}
{% simple_tag_multi 2 4 %}
{% my_input 2 'c1' %}
</body>
</html>

 views.py

imput datetime
def home(request): return render(request,'home.html',{'date':datetime.datetime.now(), 'name':'hello','age':'18'})

注意:filter可以用在if、for等语句后,simple_tag不可以

inclusion_tag

用于返回html代码片段

my_inclusin.py

from django import template

register = template.Library()


@register.inclusion_tag('result.html')  #将result.html里面的内容用下面函数的返回值渲染,然后作为一个组件一样,加载到使用这个函数的html文件里面
def show_results(n): #参数可以传多个进来
    n = 1 if n < 1 else int(n)
    data = ["第{}项".format(i) for i in range(1, n+1)]
    return {"data": data}#这里可以穿多个值,和render的感觉是一样的{'data1':data1,'data2':data2....}

 home.html

{% load my_inclusion %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}
</ul>


</body>
</html>

 index.html

{% load my_inclusion %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% show_results 10 %}
</body>
</html>

 静态文件配置

js、css、img等都叫做静态文件,那么关于django中静态文件的配置,我们就需要在settings配置文件里面写上这写内容

STATIC_URL = '/static/' #别名

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'statics'), #注意别忘了写逗号,第二个参数就是项目中你存放静态文件的文件夹名称
]

文件导入到html中的方式

img目录

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

js目录

{% load static %}
<script src="{% static "mytest.js" %}"></script>

 

posted @ 2019-02-25 19:10  等待の喵  阅读(389)  评论(0编辑  收藏  举报