• django 中模板语言的各种用法


    模板

    1、视图中使用模板

      模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户

    1.普通方法:HTML被直接硬编码在 Python 代码

    def current_datetime(request):
        now = datetime.datetime.now()
        html = "<html><body>It is now %s.</body></html>" % now
        return HttpResponse(html)
    View Code

      尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意,我们应该将页面的设计和Python的代码分离开会更干净简洁更容易维护。这时,我们可以使用 Django的 模板系统 (Template System)来实现这种模式

    2.Django 模版基本语法

    1、创建模板:
    一旦你创建一个 Template 对象,你可以用 context 来传递数据给它。 一个context是一系列变量和它们值的集合
    from django import template
    t = template.Template('My name is {{ name }}.')#创建Template 对象
    c = template.Context({'name': 'SunshineBoy'}) #创建一个 Context 对象
    print(t.render(c))
    >>>u'My name is SunshineBoy'
    #另外同一模板,可以有多个上下文,即可以同一模板渲染多个context 

    #context在Django里表现为 Context 类,在 django.template 模块里。 她的构造函数带有一个可选的参数: 一个字典映射变量和它们的值。 调用 Template 对象 的 render() 方法并传递context来填充模板

    ps:我们可以使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会更为高效

    注意:t.render(c)返回的值是一个Unicode对象,不是普通的Python字符串。 你可以通过字符串前的u来区分。 在框架中,Django会一直使用Unicode对象而不是普通的字符串

    Template加载

    通过settings去加载模板
    import datetime
    from django import template
    import DjangoDemo.settings
     
    now = datetime.datetime.now()
    fp = open(settings.BASE_DIR+'/templates/Home/Index.html')
    t = template.Template(fp.read())
    fp.close()
    html = t.render(template.Context({'current_date': now}))
    return HttpResponse(html)
    View Code
    一般来说,你在你的文件系统中存入模板,但你也可以使用自定义的template加载器去从其它地方加载你的模板。
    Django有两种方式去加载你的模板:
        1. django.template.loader.get_template(template_name):get_template通过模板名参数,返回一个模板对象,如果模板不存在,报错TemplateDoesNotExist
    from django.template.loader import get_template
    from django.template import Context
    from django.http import HttpResponse
    import datetime
     
    def current_datetime(request):
        now = datetime.datetime.now()
        t = get_template('current_datetime.html')
        html = t.render(Context({'current_date': now}))
        return HttpResponse(html)
    View Code
        2. django.template.loader.select_template(template_name_list):参数为模板名的列表,返回第一个
    存在的模板,如果列表中所有模板都不存在,就报错TemplateDoesNotExist
     
        以上函数都默认在settings.py中TEMPLATE_DIRS属性下添加的路径下查找,不过,在内部机制上,这些函数也可以指定不同的加载器来完成这些任务。
     
        加载器的设置在settings.py中的TEMPLATE_LOADERS属性中,它是一个字符串元组类型,每一个字符串代表一个loader类型。有些被默认开启,有些是默认关闭的。可以一起使用,直到找到模板为止。
     
    TEMPLATE_LOADERS = (
        #'django_mobile.loader.Loader',
        'django.template.loaders.filesystem.Loader',
        'django.template.loaders.app_directories.Loader',
        #'django.template.loaders.eggs.Loader',
    )
        1. django.template.loaders.filesystem.Loader:默认开启,从TEMPLATE_DIRS路径中加载模板
        2. django.template.loaders.app_directories.Loader:默认开启,这个装载器会在每一个INSTALLED_APPS,注册的app目录下寻找templates子目录,如果有的话,就会在子目录中加载模板。这样就可以把模板和app放在一起,方便重用。这个装载器会有一些优化,在第一次导入的时候,会缓存包含templates子目录的app
    包的列表。
        3. django.template.loaders.eggs.Loader:默认关闭,从egg文件中加载模板,egg文件类似jar包,python中打包发布代码的一种方式。和app_directories Loader类似也是从app子目录template中加载egg文件

      以上这些均是底层如何载入一个模板文件,然后用 Context渲染它,最后返回这个处理好的HttpResponse对象给用户。 我们已经优化了方案,使用 get_template() 方法代替繁杂的用代码来处理模板及其路径的工作。 但这仍然需要一定量的时间来敲出这些简化的代码。 这是一个普遍存在的重复苦力劳动。

      Django为此提供了一个捷径,让你一次性地载入某个模板文件,渲染它,然后将此作为 HttpResponse返回。

    该捷径就是位于 django.shortcuts 模块中名为 render_to_response() 的函数

    from django.shortcuts import render_to_response
    import datetime
    
    def current_datetime(request):
        now = datetime.datetime.now()
        return render_to_response('current_datetime.html', {'current_date': now})

    2、深度变量的查找

      前面,我们通过 context 传递的简单参数值主要是字符串,然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。

      在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。

    如:假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点(.)

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

    同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有 year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性:

    >>> from django.template import Template, Context
    >>> import datetime
    >>> d = datetime.date(1995, 5, 20)
    >>> d.year
    1993
    >>> d.month
    5
    >>> d.day
    2
    >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
    >>> c = Context({'date': d})
    >>> t.render(c)
    
    u'The month is 5 and the year is 1995.'

    同样,我们自定义类的实例对象也可以通过(.)来访问其实例属性

    >>> from django.template import Template, Context
    >>> class Person(object):
    ...     def __init__(self, first_name, last_name):
    ...         self.first_name, self.last_name = first_name, last_name
    >>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
    >>> c = Context({'person': Person('John', 'Smith')})
    >>> t.render(c)
    u'Hello, John Smith.'

    点语法也可以用来引用对象的* 方法*。 例如,每个 Python 字符串都有 upper() 和 isdigit() 方法

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

    ps:注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的方法

    最后,句点也可用于访问列表索引,例如

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

    3、模版语言

    模板中也有自己的语言,该语言可以实现数据展示#引用变量

    {{ item }}
    
    #引用标签(tag)
    {% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
    
      forloop.counter  #一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1,forloop.counter0 它是从0计数的
      forloop.first  #是否是循环的第一个 ,布尔值
      forloop.last  #是否是循环的最后一个 ,布尔值
    
    {% if ordered_warranty %}  {% else %} {% endif %}
    
    #继承
    母板:{% block title %}{% endblock %}   
    子板:{% extends "base.html" %}
       {% block title %}{% endblock %}
    
    #过滤器:
    {{ item.event_start|date:"Y-m-d H:i:s"}} #时间格式化
    {{ bio|truncatewords:"n" }}  #对字符串进行截段,,取这个模板变量的前 N 个字符,只能用于英文
    {{ bio|slice:"n" }}   #取变量前 N 个字符,可用于中文 
    {{ my_list|first|upper }} {{ name|lower }}
    {{ value|default:"nothing" }}  #如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值
    # Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义 {{ value|safe}} #通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义

    4、 用simple_tag 来自定义模板方法

    a、在app中创建templatetags模块

    b、创建任意 .py 文件,如:xx.py

    #!/usr/bin/env python
    #coding:utf-8
    from django import template
    from django.utils.safestring import mark_safe
       
    register = template.Library() #只能是register不能改为其它
       
    @register.simple_tag
    def my_simple_time(v1,v2,v3):
        return  v1 + v2 + v3
       
    @register.simple_tag
    def my_input(id,arg):
        result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
        return mark_safe(result)    #使用方法函数mark_safe ,使用mark_safe函数标记后,django将不再对该函数的内容进行转义.因为django默认会自动转义模板中的内容,把标签转换为相应的HTML实体。这样可以防止后端为数据库的网站被恶意脚本攻击

    c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

    {% load xx %}

    d、使用simple_tag

    {% my_simple_time 1 2 3%}
    {% my_input 'id_username' 'hide'%}

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

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    )
  • 相关阅读:
    为什么使用C#开发软件的公司和程序员都很少?
    使用Redis之前5个必须了解的事情
    这段代码为什么捕获不到异常呢?谁能给个解释,谢谢。
    git报错
    C# 常用类库(字符串处理,汉字首字母拼音,注入攻击,缓存操作,Cookies操作,AES加密等)
    你所不知道的 CSS 负值技巧与细节
    CSS 属性选择器的深入挖掘
    探秘 flex 上下文中神奇的自动 margin
    CSS 火焰?不在话下
    不可思议的纯 CSS 实现鼠标跟随效果
  • 原文地址:https://www.cnblogs.com/freely/p/6916500.html
Copyright © 2020-2023  润新知