4.Django--模板系统

Django--模板系统

模板渲染

1.基础变量渲染

关于模板渲染你只需要记两种特殊符号(语法):

  变量相关的用{{ 变量 }} 和 逻辑相关的用{% 逻辑 %}

urls.py

from app01 import views
urlpatterns = [
    url(r'^home/', views.home),
]

views.py

from django.shortcuts import render

def home(request):
    name = 'jia'
    age = 18
    hobby = ['王姑娘','与姑娘']
    info = {
        'username':'老白',
        'password':'123'
    }
    class A:
        def __init__(self):
            self.xx = 'xxxx'
        def show_phone(self):
            return 120
    a = A() #类实例化

    data = {
        'name':name,
        'age':age,
        'hobby':hobby,
        'info':info,
        'a':a,
    }
    # 模板渲染--字符串替换--替换完成之后,才能html文件数据发送给浏览器客户端
    return render(request,'home.html',data) 
	# 向home文件中传递字典类型数据

home.html:

{{变量}}{% 逻辑 %} 接收数据

万能的据点号(逗号)

<body>

<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ hobby.0 }}</p> #取出列表索引为0的数据
<p>{{ info.username }}</p> #取出字典的对应值
<p>{{ a }}</p>
<p>{{ a.xx }}</p>
<p>{{ a.show_phone }}</p> #取出类中函数
<!-- 调用方法不能加括号,意味着不能使用有参数的函数或者方法 -->

</body>

2.过滤器

在数据变量的基础上完成进一步加工

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

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

  使用管道符"|"来应用过滤器,可以链式调用

1.length :返回值的长度,作用于字符串和列表。
   {{ value|length }}

2.default :如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值
    {{ value|default:"nothing"}} 如果value没有传值或者值为空的话就显示nothing
    
3.filesizeformat:
   将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB',)  
	{{ value|filesizeformat }}
    
4.slice :可切片的数据类型
    {{value|slice:"0:2"}}  #左包右不包
        
4.date :时间格式化,如果 value=datetime.datetime.now()
    {{ value|date:"Y-m-d H:i:s"}}  #年-月-日 时:分:秒 2021-03-09 16:28:19
    
5.safe : 
    Django的模板中在进行模板渲染的时候会对HTML标签和JS等语法标签进行自动转义, 为了防止xss攻击(跨站脚本攻击), 为了在Django中关闭HTML的自动转义  
    例如:value = "<a href='#'>百度</a>"
        {{ value|safe}}
    
6.truncatechars :内容过多,不好显示,截断字符,后面的用省略号代替(...)
    例如:value = 'hello my world hello my girl'
        {{ value|truncatechars:6}} # 结果:hel... 三个点也在截断的参数里
    
7.truncatewords :内容过多,不好显示,截断多少单词(单词以空格区分),后面的用省略号代替(...)
    例如:value = 'hello my world hello my girl'
        {{ value|truncatechars:3}} # 结果:hello my world...

8.cut :移除value中所有的与给出的变量相同的字符串 
    例如:value = 'hello my world'
        {{ value|cut:' ' }} #hellomyworld 移除空格
        
9.join : 使列表中的数据连接成字符串
    	{{ list|join:',' }}     

3.标签Tags :

1.for标签 :

循环列表

<ul>
    {% for i in hobby %} 
	{#   {% for i in hobby reversed %} 倒序循环 #}
        <li>{{ i }}</li>
    {% endfor %}
</ul>

循环字典

<ul>
    {% for k,v in info.items %} <!--循环键和值,还可以用keys和values-->
        <li>{{ k }}--{{ v }}</li>
    {% endfor %}
</ul>

注:循环序号可以通过{{forloop}}本次循环对象来显示,必须在循环内部用 ,forloop是循环器,通过点来使用功能

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

forloop.parentloop :例如 hobby = [[1,2,3],[11,22,33]]

<ul>
    {% for i in hobby %}
        {% for j in i %}
            <li>{{ j }}--{{ forloop.parentloop.counter }}</li>
        {% endfor %}
    {% endfor %}
</ul>
for ... empty :给出的数据是空的或者没有被找到时,可以有所操作。
{% for person in person_list %}
    <p>{{ person.name }}</p>
{% empty %}
    <p>没有数据</p>
{% endfor %}
2.if标签

if语句支持 : and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。

{% if age > 18 %}  <!-- 比较符号两边必须有空格, 可以结合过滤一起使用 -->
    <h2>太大了</h2>
{% elif age < 18 %}
    <h2>太嫩了</h2>
{% else %}
    <h2>鸿昌</h2>
{% endif %}

也可以结合过滤器使用

{% if user_list|length > 5 %}  <!--结合过滤器来使用-->
  七座豪华SUV
{% else %}
    黄包车
{% endif %}
3.with :给一个复杂的变量起别名

注意: 等号左右不要加空格

{% with total=business.employees.count %}
    {{ total }} <!--只能在with语句体内用-->
{% endwith %}

或 with...as...

{% with business.employees.count as total %}
    {{ total }}
{% endwith %}

4.模板继承 :

​ {% block css %}..预留钩子.. {% endblock %} -- (css是名字可随意写),

{% extends 'index.html' %}继承主文件

例如:点击不同的菜单栏,只更改主页内容,菜单栏和导航栏不会变化

urls.py

from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^menu1/', views.menu1),
    url(r'^menu2/', views.menu2),
    url(r'^menu3/', views.menu3),
]

views.py

from django.shortcuts import render

def index(request):
    return render(request,'index.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')

templates目录下html文件:

index.html ,主文件至少预留三个block代码块:css,页面内容,js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .clearfix{
            content: '';
            display: block;
            clear: both;
        }
        .left-menu{
            float: left;
             200px;
            text-align: center;
            background-color:palegreen;
        }
        .content{
             800px;
            float: left;
        }
    </style>

    {% block css %} <!--预留css代码块-->
        <style>
            .header{
            background-color: yellow;
            color: aqua;
            height: 60px;
        }
        </style>
    {% endblock %}

</head>
<body>
<div>
    <div class="header">
        顶部导航菜单
        <button>个人中心</button>
    </div>

    <div class="main clearfix"> <!--菜单栏-->
        <div class="left-menu">
            <p>
                <a href="/menu1/">菜单1</a>
            </p>
            <p>
                <a href="/menu2/">菜单2</a>
            </p>
            <p>
                <a href="/menu3/">菜单3</a>
            </p>

        </div>

        <div class="content">
            {% block content %} <!--预留页面内容代码块-->
                index内容部分
            {% endblock %}
        </div>
    </div>
</div>

</body>
{% block js %} <!--预留js代码块-->
{% endblock %}
</html>

menu1.html 菜单1页面,继承主文件

{% extends 'index.html' %} <!--继承母模板-->
    {% block css %} <!--修改css样式-->
        <style>
            .header{
            background-color: pink;
            color: aqua;
            height: 60px;
        }
        </style>
    {% endblock %}

    {% block content %} <!--修改页面内容-->
        {{ block.super }} <!--保留母模板的数据-->
        菜单1部分
    {% endblock %}

menu2.html

{% extends 'index.html' %}
    {% block content %}
        菜单2部分
    {% endblock %}

menu3.html

{% extends 'index.html' %}
    {% block content %}
        菜单3部分
    {% endblock %}

5.组件

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

{% include 'nav.html' %} <!--引入nav文件-->

例如:有个如下的导航栏,nav.html

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

<div class="c2">
    <span>顶部导航栏</span>
</div>

</body>
</html>

嵌入导航栏的页面,xx.html

<body>
{% include 'nav.html' %} <!--引入nav文件-->
    
<div>
    <h1>xx页面</h1>
</div>
</body>

6.自定义标签和过滤器

流程

1 创建应用
2 在应用中创建一个templatetags的文件,名称必须叫templatetags
3 在templatetags文件夹中创建一个py文件,名称随意mytages
4 文件中写如下内容

from django import template

# 注册器变量名称必须叫做register
register = template.Library()

#1.自定义过滤器: 1 写函数   2 通过filter装饰器装饰函数
#过滤器最多两个参数
@register.filter
def addxx(v1):  #一个参数,这个参数是{{ name|addxx }}的name数据
    s = v1 + 'xx'
    return s

@register.filter
def addxx2(v1,v2):  #两个参数,这个参数是{{ name|addxx:'oo' }}的name和oo数据
    s = v1 + 'xx' +v2
    return s

#2.自定义标签
@register.simple_tag
def xxtag(v1,v2,v3): #自定义标签,参数可以是任意个数
    return '+'.join([v1,v2,v3])

使用 home.html

{% load mytages %} <!--必须先加载,重启项目,才能使用自定义标签和过滤器-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--使用过滤器-->
<p>{{ name|addxx }}</p>
<p>{{ name|addxx2:'oo' }}</p>
    
<!--使用标签-->
<p>{% xxtag 'aa' 'bb' 'cc' %}</p>
    
</body>
</html>
inclusion_tag 自定义标签:主要用来做动态组件
1 创建应用
2 在应用中创建一个templatetags的文件,名称必须叫templatetags
3 在templatetags文件夹中创建一个py文件,名称随意mytages
4 文件中写如下内容

from django import template

# 注册器变量名称必须叫做register
register = template.Library()

@register.inclusion_tag('nav.html') #参数就是那个组件html文件
def custom_nav(v1): #参数可以是任意个数
    print(v1) #打印的是接收的的hobby数据['与姑娘', '李姑娘', '加固年']
    return {'nav_data':v1} #nav.html里用什么数据就返回什么数据,必须是字典

导航栏: nav.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .c2{
            background-color: aqua;
            height: 60px;
        }
        .c1{
            color: blue;
        }
    </style>
</head>
<body>
<div class="c2">
    {% for item in nav_data %}
        <span class="c1">{{ item }}</span>
    {% endfor %}
</div>
</body>
</html>

home.html

在某个html文件中使用这个动态组件

{% load mytages %}
{% custom_nav hobby %}
{% load mytages %} <!--必须先加载,才能使用自定义标签和过滤器-->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% custom_nav hobby %} <!--使用标签,把hobby数据传到自定义标签函数中-->
</body>
</html>    

views.py

from django.shortcuts import render
def home(request):

    hobby = ['王姑娘2', '于姑娘2', '何姑娘3']
    data = {
        'hobby':hobby,
    }
    # 模板渲染--字符串替换--替换完成之后,才能html文件数据发送给浏览器客户端
    return render(request, 'home.html', data)

7.静态文件引入设置

1 在项目根目录下创建一个文件夹,名称随意,比如叫做jingtaiwenjianjia

2 将所需静态文件放到这个文件夹中,例如:bootstrap 文件

3 在settings.py文件中做如下配置

STATIC_URL = '/static/'  #静态文件夹路径别名,

STATICFILES_DIRS = [ #导入静态文件路径方向
    os.path.join(BASE_DIR, 'jingtaiwenjianjia'),
]

4 在html文件中就可以通过static别名来进行静态文件的引入了

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 方式1 -->
{#    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">#}
     <!-- 方式2,别忘了先load static -->
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">

</head>
<body>

<h1>这是kk页面</h1>

<table class="table table-bordered table-striped table-hover">
    <thead>
    <tr>
        <th>姓名</th>
        <th>爱好</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>老王</td>
        <td>隔壁</td>
    </tr>
    <tr>
        <td>老白</td>
        <td>鸡哥</td>
    </tr>
    <tr>
        <td>鸡哥</td>
        <td>老王</td>
    </tr>
    </tbody>
</table>
</body>
</html>
原文地址:https://www.cnblogs.com/jia-shu/p/14589769.html