django框架之模板层

模板层

标签
过滤器
自定义标签、过滤器、inclusion_tag
模板的继承
模板的导入

1. 后端向前端页面传递数据

1)有两种方式

方式1

return render(request, 'index.html', {'n': n})

方式2:将当前所在的名称空间中的变量名全部传递给前端页面

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

后端可以给html传递的数据有哪些:

python所有的基本数据类型
函数名(传函数名会自动加括号执行,不支持传参)
对象(相当于在前端页面打印了该对象)

2)前端调用数据

前端可以调用python自带的不需要传参内置方法

前端获取后端传递过来的容器类型的内部元素,统一采用句点符:

有序类型  直接(.索引)访问
字典      直接(.key)
{{ t }},{{ t.1 }} 数字对应的就是数据的索引

模板语法

{# 模板语法的注释,不会展示到前端页面 #}

 <!--原生html的注释,会展示到前端页面-->

2. 前端对数据的修饰

两种特殊符号:

{{ }} 变量相关

{% %} 逻辑相关

取消转义:

前端:|safe   *****

后端:

from django.utils.safestring import mark_safe 

mark_safe('<h1>我是h1标签</h1>')

1)过滤器

 {{ value|filter_name:参数 }}

会将|前的数据作为参数传递给后面的函数

{{ s|length }}             统计字符串的长度
{{ flag|default:'xxx' }}   获取数据,为空就返回default后面默认的参数值"xxx"
{{ ctime|date:'Y-m-d'}}    格式化时间(不要加百分号%)
{{ str|slice:'0:8'}}       字符串的切片操作{{ str|slice:'0:8:2'}}
{{ str|truncatechars:10}}  截取规定长度的字符串,以...结尾
{{ str|truncatewords:4}}   按照空格截取文本内容
{{ n|add:1}}               同类型拼加,否则返回""
{{ file_size|filesizeformat}}  将数字格式化成表示文件大小的单位
{{ 标签文本|safe}}               取消转义,防止脚本攻击页面,告诉页面safe,则会执行标签

后端取消转义:

2)标签

for循环

{#l = ['a', 'b', 'c', 'd', 'e']#}
{% for foo in l %}
    <p>{{ foo }}</p>
{% endfor %}


输出:
a
b
c
d
e

   forloop:自定义对象

forloop.first  判断是否为第一个(布尔值)

forloop.last  判断是否为最后一个(布尔值)

forloop.counter0  当前循环的索引值

forloop.counter  当前循环的索引值,从1开始

forloop.revcounter  未循环数+1

forloop.revcounter0  未循环数

forloop.parentloop  本层循环的外层循环{}

{#l = ['a', 'b', 'c', 'd', 'e']#}
{% for foo in l %}
    <p>{{ forloop }}</p>
{% endfor %}


输出:
a {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 5, 'revcounter0': 4, 'first': True, 'last': False} b {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False} c {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False} d {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False} e {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}

if 判断

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

{#i = []#}
{% if i %}
    <p>i不为空</p>
    {% else %}
    <p>i为空</p>
{% endif %}

 for & if 嵌套使用

循环变量为空时,会执行empty后面的代码;

不为空,执行if判断。如容器中元素较少时,优先执行forloop.first,还有元素才会执行forloop.last,前两条执行完毕多出来的元素才会执行else

列表循环

{# l = ['a', 'b', 'c', 'd', 'e'] #}
{% for foo in l %}
    {% if forloop.first %}
        <p>这是l第一次循环</p>
    {% elif forloop.last %}
        <p>这是l最后一次循环</p>
    {% else %}
        <p>在路上...</p>
    {% endif %}
    {% empty %}
        <p>容器类型为空,无法for循环!!!!</p>
{% endfor %}


输出:
这是l第一次循环
在路上...
在路上...
在路上...
这是l最后一次循环


{# 换为 i = [] #}
容器类型为空,无法for循环!!!!

字典循环

起别名:当名称过长时可以起别名,只能在with内部是使用,并且本名在with内部也可以使用

{% with d.hobby.1 as h %}
    <p>{{ h }}</p>
{% endwith %}

{#d = {'name': 'Tom', 'password': '222', 'hobby': ['看书', '写字']}#}
{% for foo in d %}
    <p>{{ foo }}</p>
{% endfor %}

{% for foo in d.keys %}
    <p>{{ foo }}</p>
{% endfor %}

{% for foo in d.values %}
    <p>{{ foo }}</p>
{% endfor %}

{% for foo in d.items %}
    <p>{{ foo }}</p>
{% endfor %}

<p>{{ d.hobby.1 }}</p>
{% with d.hobby.1 as h %}
    <p>{{ h }}</p>
    <p>{{ d.hobby.1 }}</p>
{% endwith %}



输出:
name      # d
password
hobby

name    # d.keys 
password
hobby

Tom     # d.values 
222
['看书', '写字']

('name', 'Tom')    #d.items 
('password', '222')
('hobby', ['看书', '写字'])

写字
写字
写字
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^reg/', views.reg),
    url(r'^home/', views.home),
    url(r'^login/', views.login),
]
urls.py
from django.shortcuts import render
from django.utils.safestring import mark_safe
from datetime import datetime


def index(request):
    n = 6969
    s = '你好!'
    i = []
    l = ['a', 'b', 'c', 'd', 'e']
    d = {'name': 'Tom', 'password': '222', 'hobby': ['看书', '写字']}
    t = ('red', 'blue', 'green')
    st = {'rain', 'sun'}
    st = '<h1>今天天气真好!</h1>'
    xxx = mark_safe(st)
    res = 'hello baby~~ bay~bay~bay~~~'
    file_size = 215492235
    sr = '<script>alert(123)</script>'
    ctime = datetime.now()

    def func():
        return '被调用了?'

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

        def func(self):
            return self.name

        @classmethod
        def index(cls):
            return 'cls'

        @staticmethod
        def bar():
            return 'bar'

        def __str__(self):
            return "谁?"

    obj = Demo('Tom')

    # return render(request, 'index.html', {'n': n})
    return render(request, 'index.html', locals())


def home(request):
    return render(request, 'home.html')


def login(request):
    return render(request, 'login.html')


def reg(request):
    return render(request, 'reg.html')
views.py

 3)自定义标签、过滤器、inclusion_tag

♤  自定义必须做的三件事:

1. 在应用名下新建一个名为 templatetags文件夹(必须叫这个名字)

2. 在该新建的文件夹内新建一个任意名称的py文件

3. 在该py文件中需要固定写下面两句代码

from django import template

register = template.Library()

 

♤  关于自定义

自定义标签:只能传两个值

自定义过滤器:可以传多个值

自定义 inclusion_tag:支持一个变量的预备模板

使用自定义的过滤器、标签、inclusion_tag: 必须先在需要使用的html页面加载你的py文件

在要使用的.html页面导入

{% load my_tags %}

示例:my_tags.py

from django import template

register = template.Library()


# 自定义过滤器
@register.filter(name='and')
def index(a, b):
    return a + b


# 自定义标签
@register.simple_tag(name='aaa')
def plus(a, b, c):
    return a + b + c


# 自定义inclusion_tag
@register.inclusion_tag('logino.html', name='login')  # 将数据放到‘logino.html’渲染后返回给目标页面
def login(n):
    # l = []
    # for i in range(n):
    #     l.append('第%s个' % i)
    l = ['第%s个'%i for i in range(n)]
    return {'l': l}   # 字典字典!!!

logino.html文件 :将其他的标签都删除,只放下面的代码

<ul>
    {% for foo in l %}
        <li>{{ foo }}</li>
    {% endfor %}
</ul>

前端.html调用:

{% load my_tags %}   # 加载my_tags.py文件
{{ n|and:6 }}     # 自定义过滤器
{% aaa 1 2 3 %}   # 自定义标签
{% login 5 %}     # 自定义inclusion_tag

 4)模板的继承与导入

♤  首先需要在被继承的模板中划分多个区域

{% block 给区域起的名字 %}

    被划分的区域代码

{% endblock %}

通常情况下,一个模板中至少有三个区域:

css:页面css代码块

js:页面js代码块

content:页面主体内容

♤  子板继承模板

将模板清空

先继承模板所有内容

然后根据block块的名字修改指定区域的内容

{% extends 'home.html' %}   {# 继承模板所有内容 #}

{% block content %}
    <h1>注册页面</h1>
    <form action="">
        <p>username:<input type="text" class="form-control"></p>
        <p>password:<input type="text" class="form-control"></p>
        <input type="submit" class="btn btn-danger pull-right" >
    </form>
{% endblock %}

♤  模板的导入

将一段html当做模块导入到另一个.html文件页面展示

{% include '想导入的.html文件'%}

5)静态文件配置

 动态获取前缀,代码放在head标签里面

    {% load static %}

    <link rel='stylesheet' href="{% static 'css/mycss.css'%}">  # 第一种方式
    <link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css">  # 第二种方式 >

 

 

posted @ 2019-06-11 19:51  zhoyong  阅读(319)  评论(0编辑  收藏  举报