六、Django之Template

一、Template由来

1、任何前端页面的改动都和后端python有关;

2、前端HTML和后端python分开能让网站更加清晰;

3、前后端分离的趋势下,所有前端页面放一起更加方便前端人员调试和编码。

二、Django中的template

1、定义模板引擎

TEMPLATES = [
    {
       #Django默认模板引擎,也可以设置jinja2模板
       #django.template.backends.jinja2.Jinja2
        'BACKEND': 'django.template.backends.django.DjangoTemplates',

       #设置template位置
        'DIRS': [os.path.join(BASE_DIR, 'templates')]

        #告诉引擎是否需要查找内部app下的模板
        'APP_DIRS': True,
        #其他选项
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

  

2、渲染模板

(venv) D:\xuequn\venv\Scripts\firstapp>python manage.py shell
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

>>> from django.template import Template
>>> t=Template('my name is {{name}}.')
>>> print t
<django.template.base.Template object at 0x00000000038F9F60>
>>> from django.template import Context
>>> c=Context({'name':'xuequn'})
>>> t.render(c)
u'my name is xuequn.'

  

其实模板选项和字符串format格式化类似,只不过django中使用render进行渲染。

>>> '{name} is {li}'.format(**{'name':'xuequn','li':'haha'})

3、Django中使用模板

Django 模板解析非常快捷。 大部分的解析工作都是在后台通过对简短正则表达式一次性调用来完成。 这和基于 XML 的模板引擎形成鲜明对比,那些引擎承担了 XML 解析器的开销,且往往比 Django 模板渲染引擎要慢上几个数量级。

from django.shortcuts import render,HttpResponse
from django.template.loader import get_template #记得导入
import datetime
from django.template import Template,Context


# 视图方法1
def current_time(req):
    #原始的视图函数,通过传递字符串或者直接读取文件内容为字符串的方法
     now=datetime.datetime.now()
     html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now
     return HttpResponse(html)


#视图方法2
def current_time(req):
#使用Template、Context以及render方法进行动态内容渲染 now=datetime.datetime.now() #t=Template('<html><body>现在时刻是:<h1 style="color:red">{{current_date}}</h1></body></html>') t=get_template('current_datetime.html') c=Context({'current_date':now}) html=t.render(c) return HttpResponse(html) #视图方法3(推荐) def current_time(req):
#直接通过Django的render方法,将html内容以及变量传入即可。 now=datetime.datetime.now() return render(req, 'current_datetime.html', {'current_date':now})

  

4、万能的点号(.)

使用小数点来得到字典的key,属性,对象的索引和方法。

通过(.)访问字典的key:

>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c= Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'

  

通过(.)来访问对象的属性:

>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day

  

调用列表的索引:

>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Contexst({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'

  

点还可以用来访问对象的方法,例如Python的string有upper()和isdigit()方法:

>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 - 123 - True'

 

注意,调用方法时你不能加括号,你也不能给方法传递参数
你只能调用没有参数的方法,后面我们会解释这些
总结一下,当模板系统遇到变量名里有小数点时会按以下顺序查找:
1,字典查找,如foo["bar"]
2,属性查找,如foo.bar
3,方法调用,如foo.bar()
3,列表的索引查找,如foo[bar]
小数点可以链式查询,例如{{ person.name.upper }}表示字典查询person['name']然后调用upper()方法。

5、不合法的变量处理

默认情况下如果变量不存在,模板系统会把它渲染成空string,例如:

>>> from django.template import Template, Context
>>> t = Template('Your name is {{ name }}.')
>>> t.render(Context())
'Your name is .'
>>> t.render(Context({'var': 'hello'}))
'Your name is .'
>>> t.render(Context({'NAME': 'hello'}))
'Your name is .'
>>> t.render(Context({'Name': 'hello'}))
'Your name is .'

  

6、Context对象

大多数情况下你初始化Context对象会传递一个字典给Context(),一旦你初始化了Context,你可以使用标准Python字典语法增减Context对象的items:

>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
''
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'

  

Context对象是一个stack,你可以push()和pop()
如果你pop()的太多的话它将触发django.template.ContextPopException:

>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.push()
>>> c['foo'] = 'second level'
>>> c['foo']
'second level'
>>> c.pop()
>>> c['foo']
'first level'
>>> c['foo'] = 'overwritten'
>>> c['foo']
'overwritten'
>>> c.pop()
Traceback (most recent call last):
...
django.template.ContextPopException

  

6、变量的过滤器

模板过滤器是变量显示前转换它们的值的方式,看起来像下面这样:

{{ name|lower }}

  更多实例:

# 1  add          :   给变量加上相应的值
   #
   # 2  addslashes   :    给变量中的引号前加上斜线
   #
   # 3  capfirst     :    首字母大写
   #
   # 4  cut          :   从字符串中移除指定的字符
   #
   # 5  date         :   格式化日期字符串
   #
   # 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
   #
   # 7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值


#实例:

#value1="aBcDe"
{{ value1|upper }}<br>

#value2=5
{{ value2|add:3 }}<br>

#value3='he  llo wo r ld'
{{ value3|cut:' ' }}<br>

#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>

#value5=[]
{{ value5|default:'空的' }}<br>

#value6='<a href="#">跳转</a>'

{{ value6 }}

{% autoescape off %}
  {{ value6 }}
{% endautoescape %}

{{ value6|safe }}<br>

{{ value6|striptags }}

#value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>

#value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
 

  

7、标签(tag)

if

{% if %}

{% elif %}

{% else %}

 

for

{% for obj in list %}
    <li>{{ obj.name }}</li>
{% endfor %}

 for标签还有几个有用的内置变量:

1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:

    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}
2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0
3,forloop.revcounter
4,forloop.revcounter0
5,forloop.first当第一次循环时值为True,在特别情况下很有用:

    
    {% for object in objects %}   
         {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
         {{ object }}   
        </li>  
    {% endfor %}  

 

empty

  {%  for i in li %}
          <li>{{ forloop.counter0 }}----{{ i }}</li>
      {% empty %}
          <li>this is empty!</li>
      {% endfor %}

 

csrf_token 

{%csrf_token%}:csrf_token标签

  

url

{% url %}:  引用路由配置的地址

  

with

用更简单的变量名替代复杂的变量名

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}

  

verbatim

禁止render

{% verbatim %}
         {{ hello }}
{% endverbatim %}

  

load 

加载标签库

{% load %}

  

自定义filter和simple_tag

mytag.py

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

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

#自定义filter
@register.filter
def filter_multi(v1,v2):
    return  v1 * v2

#simple_tag
@register.simple_tag
def simple_tag_multi(v1,v2):
    return  v1 * v2


@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

  

调用

{% load mytag %}   #首行
   
 # num=12
{{ num|filter_multi:2 }} #24

{{ num|filter_multi:"[22,333,4444]" }}

{% simple_tag_multi 2 5 %}  参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}

  

注意:

  • 在app中创建templatetags模块(必须的)
  • 创建任意 .py 文件,如:my_tags.py
  • 在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %}
  • 使用simple_tag和filter(如何调用)
  • 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
  • filter可以用在if等语句后,simple_tag不可以
{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

  

8、模板继承

include 模板标签

extend(继承)模板标签

猜你喜欢

转载自www.cnblogs.com/skyflask/p/9314529.html
今日推荐