从零开始的Linux运维屌丝之路,资源免费分享平台   运维人员首选:简单、易用、高效、安全、稳定、社区活跃的开源软件

Django模板语言 HTML语法

发布:蔺要红07-15分类: Python


官方文档
 

{#模板语言测试的页面#} #注释

两种特殊符号:  {{  }}  和  {% %}

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

变量

Filters的使用

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

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

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

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

注意事项:

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

Django的模板语言中提供了大约六十个内置过滤器。

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

{{ value|default:"自定义的内容"}}  #如果后端没有传值,则使用自定义的内容

length :返回值的长度,作用于字符串和列表。

{{ value|length }}  #返回value的长度,如 value=['a', 'b', 'c', 'd']的话,就显示4.

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

{{ value|filesizeformat }}  #如果 value 是 123456789,输出将会是 117.7 MB。

slice :切片取值

{{value|slice:"2:-1"}}  
{{ name_list|slice:":-1" }}  |  {{ name|slice:"0:1" }}

date :格式化

{{ value|date:"Y-m-d H:i:s"}}
{{ now|date:"Y-m-d H:i:s" }}      #2019-07-16 12:00:07

safe : Django的模板中会对HTML标签和JS等语法标签进行自动转义。但是有的时候我们可能不希望这些HTML元素被转义,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。

{{ value|safe}}     #{{ a_html|safe }}  /后端      a_html = "<a href='http://www.baidu.com'>后端A标签</a>"

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

参数:截断的字符数

{{ value|truncatechars:20}}

自定义filter

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

变量(输入)的值 - -不一定是一个字符串
参数的值 - 这可以有一个默认值,或完全省略
 
首先创建目录和文件(存放方法的文件和目录)/定义好方法以后即可在html里使用

appweb
    __init__.py
    models.py
    templatetags/  # 在app01下面新建一个package package
        __init__.py
        myfilter.py  # 建一个存放自定义filter的文件
    views.py


使用方法:和Django自带的语法一样
 
{{ name|custom }}
{{ name|add_custom:"传参数的自定义" }}


Tags


For循环可用参数
 
Variable Description
forloop.counter 当前循环的索引值(从1开始)
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环
 
{% for name in name_list %}
    <li>{{ name }}</li>
{% endfor %}
{% for name in name_list %}
    {% if forloop.first %}
        <ul style="color:red">{{ forloop.counter }}.{{ name }}</ul>
    {% endif %}
    {% if forloop.last %}
        <li style="color:yellowgreen">{{ forloop.counter }}.{{ name }}</li>
    {% else %}
        <li>{{ forloop.counter }}.{{ name }}</li>
    {% endif %}
{% endfor %}

for循环empty用法
{% for names in name_lists %}
    <li>{{ names }}</li>
{% empty %}
    <li>暂时没有数据</li>

if语句

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

{% if user_list %}
  用户人数:{{ user_list|length }}
{% elif black_list %}
  黑名单数:{{ black_list|length }}
{% else %}
  没有用户
{% endif %}
{% if user_list|length > 5 %}
  七座豪华SUV
{% else %}
    黄包车
{% endif %}
{% if a > b and b > c %}
<li {% if author_list %} class="active"{% endif %}><a href="/author_list/">作者列表</a></li>

with语句  (想当与取一个别名,下面书写方便)
{% with name=namelist|length %}
{% if name >= 5 %}
    <p>人数大于5</p>
{% else %}
    <p>人数小于5</p>
{% endif %}
{% endwith %}

views.py
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def dream(self):
        return "类里的方法"
    def __str__(self):        # python3
        return "<Person Object: {}{}>".format(self.name,self.age)
    def __unicode__(self):    # python2
        return "<Person Object: {}>".format(self.name)

def index(request):
    file_size = 1239312312324
    linyaohong = "蔺要红"
    age = 18
    from datetime import datetime
    now = datetime.now()
    print(now)
    messages = ""
    namelist = ["钢铁侠","蜘蛛侠","绿巨人","雷神","黑寡妇","绯红女巫"]
    nameidct = { "first_name":"黑豹","last_name":"星爵" }
    p1 = Person("蚁人",109)
    p2 = Person("奇异博士",433)
    plist = [p1,p2]
    a_html = "<a href='http://www.baidu.com'>后端A标签</a>"
    p_str = '''
        随机看功能:是用户发布视频类信息,其他用户点击随机看,可以看到其他人发送的视频信息。
        关注信息:是用户可以无限制的关注他人,他人也可以被无限度的关注,关注他人后,他人发送的任何信息。
        包括文字、图片、视频、都会出现在他人的关注圈内被他人看到。
        第二
        用户点击+号可以直接发送视频、文字或者图片信息到关注圈,如果是发送视频会额外的发送到随机看,供陌生人随机刷到观看
    '''
    return render(
        request,"html/index.html",
        {
            "name":linyaohong ,
             "age1":age ,
             "error":messages,
             "name_list": namelist,
             "name_dict": nameidct,
             "person1":p1,
             "person2": p2,
             "p_list": plist,
             "filesize": file_size,
             "now": now,
             "a_html": a_html,
             "p_str": p_str,
        }
    )

HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>模板语言测试的页面</h1>
{#模板语言测试的页面#}
<p>-------------------------变量</p>
<p></p>
{{ name }}
<p>-------------------------自定义的filter</p>
{% load myfilter %}
{{ name|custom }}
<p></p>
{{ name|add_custom:"传参数的自定义" }}
<p></p>
{{ name_dict.first_name|custom }}
<p>-------------------------取长度</p>
{{ name }}&nbsp;{{ name|length }}
<p>-------------------------文件大小 {{ filesize|filesizeformat }}</p>
<p></p>
{{ age1 }}
<p>-------------------------默认值</p>
{{ bucunzai|default:"这个变量没有传值,使用的是默认值" }}
<p>*****传时间</p>
{{ now }}
<p></p>
{{ now|date:"Y-m-d H:i:s" }}
<p>***取a标签0</p>
{{ a_html }}
<p></p>
{{ a_html|safe }}
<hr>
<p>**文章摘要</p>
{{ p_str }}
<p></p>
<hr>
{{ p_str|truncatechars:20 }}
<hr>
<p>*****列表:</p>
{{ name_list }}
<p>**切片:</p>

<p></p>
{{ name|slice:"0:1" }}
<p></p>
{{ name_list|slice:":" }}
<p>**取列表里的值</p>
<p>**取第一个</p>
{{ name_list.0 }}
<hr>
<p>*****字典</p>
{{ name_dict }}
<p></p>
{{ name_dict.first_name }}|{{ name_dict.last_name }}
<P>-------------------------使用对象,如果后端没定义__str__方法、则会返回一个对象</P>
{{ person1 }}|{{ person2 }}
<P>-------------------------使用对象的方法</P>
<p>*****只能传不带参数方法</p>
{{ person1.name }}|{{ person1.age }}|{{ person1.dream }}
<p>属性的优先级要大于方法的优先级,字典key的优先级大于内置items()的优先级</p>
<hr>
{{ p_list }}
<p></p>
{{ p_list.0 }}
<p>-------------------------取列表里的值</p>
{{ p_list.0.name }}
<p></p>
{{ p_list.1.name }}
<p>-------------------------for语句</p>
{% for names in name_lists %}
    <li>{{ names }}</li>
{% empty %}
    <li>暂时没有数据</li>
{% endfor %}
<p>***</p>
{% for names in name_list %}
    <li>{{ names }}</li>
{% empty %}
    <li>暂时没有数据</li>
{% endfor %}
<p>***</p>
{% for name in name_list %}
    {% if forloop.first %}
        <ul style="color:red">{{ forloop.counter }}.{{ name }}</ul>
    {% endif %}
    {% if forloop.last %}
        <li style="color:yellowgreen">{{ forloop.counter }}.{{ name }}</li>
    {% else %}
        <li>{{ forloop.counter }}.{{ name }}</li>
    {% endif %}
{% endfor %}
<hr>
<p>-------------------------if语句</p>
{% if namelist|length >= 5 %}
    <p>人数大于5</p>
{% else %}
    <p>人数小于5</p>
{% endif %}
<p>-------------------------with用法</p>
{% with name=namelist|length %}
{% if name >= 5 %}
    <p>人数大于5</p>
{% else %}
    <p>人数小于5</p>
{% endif %}
{% endwith %}

</body>
</html>
 
母版的使用

使用注意事项:
1、{
% extends "html/base.html" %} 注意母版文件需要加""引号、并且必须放到第一行
2、 可以定义多个block,通常会额外定义一个page-css和page-js两个模块
 
#1.首先把公共部分提取出来,放到base.html

#2.模板页面:base.html,
定义block,把每个页面不同的部分 区分出来
{# 这里是每页面不同的部分 #}
    {% block page-main %}
    {% endblock %}
    
#普通页面中:
{#首先继承模板#}
{% extends 'html/base.html' %}
{# 其次把自己的页面内容,写到模板里相应的位置 #}
{% block page-main %}
    写入普通页面的部分
{% endblock %}

关于JS/CSS如果页面单独用到也可也使用这样的方法:
# 首先base.html在css样式里加入block
<head>
.......
.......
    <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
    {% block page-css %}
    {% endblock %}
</head>

#然后单独的页面引用

{% block page-css %}  #引用
    <link rel="stylesheet" href="/static/book_css.css">
{% endblock %}


组件

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

{% include 'navbar.html' %}

动态加载静态文件(一般没人闲的没事改)
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
    os.path.join(BASE_DIR, 'static2'),
]
{% load static %}

<link rel="stylesheet" href={% static "fontawesome/css/font-awesome.min.css" %}>  # 动态引用静态文件
{# <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css"> #} # 非动态引用静态文件
某个文件多处被用到可以存为一个变量
{% load static %}

{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
 simple_tag

和自定义filter类似,只不过接收更灵活的参数。定义注册simple tag

@register.simple_tag(name="plus")
def plus(a, b, c):
    return "{} + {} + {}".format(a, b, c)
使用自定义simple tag

{% load app01_demo %}

{# simple tag #}
{% plus "1" "2" "abc" %}

inclusion_tag

多用于返回html代码片段

具体的实现方式:
    1. 定义阶段
        1. 在app下面新建一个python的包:templatetags
        2. 在上面的Python包中新建一个Python文件,名字随意
        3. 在上述python文件中:
            from django import template
            # 生成一个注册用的实例
            register = template.Library()
            # 定义并注册一个自定义的filter函数

@register.inclusion_tag('result.html')  #不定义name 在html里使用 show_results(函数名)
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}

    2. 调用阶段:
        1. 在Django的模板文件中,导入刚才新建的python文件
            {% load py文件名 %}
        2. 按照filter的语法调用
            {{ show_results }}

templatetags/my_inclusion.py

from django import template

register = template.Library()


@register.inclusion_tag('result.html')  #不定义name 在html里使用 show_results(函数名)
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}
templates/snippets/result.html
<ul>
  {% for choice in data %}
    <li>{{ choice }}</li>
  {% endfor %}
</ul>

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>inclusion_tag test</title>
</head>
<body>

{% load inclusion_tag_test %}

{% show_results 10 %}
</body>
</html>
温馨提示如有转载或引用以上内容之必要,敬请将本文链接作为出处标注,如有侵权我会在24小时之内删除!

欢迎使用手机扫描访问本站