zoukankan      html  css  js  c++  java
  • The Definitive Guide To Django 2 学习笔记(七) 第四章 模板 (三)使用模板系统

    接下来,我们开始学习如何使用模板系统,但我们并不和前面说的View相结合,我们的这里的目的是展示模板系统是如何独立于Django框架运行的。下面是在pyhon代码中使用Django模板系统的基础例子:

    1.通过提供原生文本代码创建Template模板对象

    2.调用Template对象的render()方法并传入所给的参数(上下文文本)。

    >>> from django import template
    >>> t = template.Template('My name is {{ name }}.')
    >>> c = template.Context({'name': 'Adrian'})
    >>> print t.render(c)
    My name is Adrian.
    >>> c = template.Context({'name': 'Fred'})
    >>> print t.render(c)
    My name is Fred.

    创建模板对象

    最简单的创建Template对象的方法就是直接实例化一个出来。Template类在Django.Template module里,构造函数需要一个参数,原生template 代码。接下来我们将一步步看看在python交互解释器中是如何工作的。

    在myiste项目中,输入 python manage.py shell 启动交互解释器。

    (原文中此处解释了为什么没有使用python而是使用了python shell,主要是此处使用python shell 方便了配置。)

    一个简单的例子:

    >>> from django.template import Template
    >>> t = Template('My name is {{ name }}.')
    >>> print t

    你会在显示中看到:

    <django.template.Template object at 0xb7d5f24c>

    0xb7d5f24c 每次都是不一样的,但他们是有关系的,是python用来识别Template对象的标识。

    调用模板

    一旦你创建模板完毕,你可以通过把数据传给一个context然后传给模板,context是一个简单的模板变量的合集,它包含了模板中变量的值。

    context是django.template module中的值。它的构造函数包括一个参数,字典映射变量给值。调用Template对象的render()方法来填充模板。、:

    >>> from django.template import Context, Template
    >>> t = Template('My name is {{ name }}.')
    >>> c = Context({'name': 'Stephane'})
    >>> t.render(c)
    u'My name is Stephane.'

    多上下文,多模板

    一旦你创建了Template对象,你可以给它赋予多个context,参考下面的例子:

    >>> from django.template import Template, Context
    >>> t = Template('Hello, {{ name }}')
    >>> print t.render(Context({'name': 'John'}))
    Hello, John
    >>> print t.render(Context({'name': 'Julie'}))
    Hello, Julie
    >>> print t.render(Context({'name': 'Pat'}))
    Hello, Pat

    不论什么时候你这样使用模板,创建模板对象一次,然后显示它们多次比较有效率:

    # 坏的编码
    for name in ('John', 'Julie', 'Pat'):
    t = Template('Hello, {{ name }}')
    print t.render(Context({'name': name}))
    # 好的编码
    t = Template('Hello, {{ name }}')
    for name in ('John', 'Julie', 'Pat'):
    print t.render(Context({'name': name}))

     上下文变量查找

    之前的例子中,我们都是把简单的变量传递给了上下文Context,实际上,模板系统还可以处理更为复杂的数据类型。

    >>> 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)
    u'Sally is 43 years old.'

    同样,我们可以使用自定义类:

    >>> 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中的string类型的对象有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'

    注意,在调用方法的时候不需要外面的括号,也不可以向方法传递参数,你只可以调用无参方法。

    最后,点还可以用来访问list中的序列,如下:

    >>> 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.'

    负数序号是不允许的,{{items.-1}}会引发TemplateSyntaxError异常。

    方法调用行为

    方法调用要比其他类型的查找稍微复杂一些,下面是一些需要记住的:

    如果在查找方法期间,方法执行过程中出现了异常,异常将会被弹出来,除非异常拥有silent_variable_failure标记而且该标记为true.如果异常拥有silent_variable_failure标记,变量将会被赋予空字符,如下例:

    >>> t = Template("My name is {{ person.first_name }}.")
    >>> class PersonClass3:
    ... def first_name(self):
    ... raise AssertionError, "foo"
    >>> p = PersonClass3()
    >>> t.render(Context({"person": p}))
    Traceback (most recent call last):
    ...
    AssertionError: foo
    >>> class SilentAssertionError(AssertionError):
    ... silent_variable_failure = True
    >>> class PersonClass4:
    ... def first_name(self):
    ... raise SilentAssertionError
    >>> p = PersonClass4()
    >>> t.render(Context({"person": p}))
    u'My name is .'

    1.方法调用只在方法不需要参数的时候起作用,否则,系统将会移动到下一个查找类型。

    2.显示,有些方法会有一些副作用,安全漏洞,允许模板系统访问他们。

       譬如,有一个BankAccount类型的对象,该对象有个delete()方法。如果模板系统包括类似的语句{{account.delete}},account是一个BankAccount类型的对象,该对象会被展示模板时被删除。

       为了防止对象被删除,给方法添加一个alters_data的标记:

    def delete(self):
    # Delete the account
    delete.alters_data = True

    模板系统不会执行任何被这样标记了的方法,在这个例子中,展示模板时,delete()方法不会被执行,取而代之的是静默的失败。

    无效的变量如何被处理

    默认情况下,如果变量在模板系统中不存在,将返回空字符串,静默地失败。考虑下面的例子:

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

    系统静默地失败而非抛出异常是因为要平滑地处理异常,上面的例子中,所有的查找失败都是因为变量大小写错误或是名字不对,在现实世界中,仅仅因为这样的错误而使网站不可访问时不可接受的。

    上下文对象

    多数情况下你将会实例化一个Context对象,利用pythong字典的特性,你可以在创建了Context对象之后对其中的的每一项进行添加或是删除。

    >>> from django.template import Context
    >>> c = Context({"foo": "bar"})
    >>> c['foo']
    'bar'
    >>> del c['foo']
    >>> c['foo']
    Traceback (most recent call last):
    ...
    KeyError: 'foo'
    >>> c['newvariable'] = 'hello'
    >>> c['newvariable']
    'hello'
  • 相关阅读:
    XAML学习笔记之Layout(五)——ViewBox
    XAML学习笔记——Layout(三)
    XAML学习笔记——Layout(二)
    XAML学习笔记——Layout(一)
    从0开始搭建SQL Server 2012 AlwaysOn 第三篇(安装数据,配置AlwaysOn)
    从0开始搭建SQL Server 2012 AlwaysOn 第二篇(配置故障转移集群)
    从0开始搭建SQL Server 2012 AlwaysOn 第一篇(AD域与DNS)
    Sql Server 2012 事务复制遇到的问题及解决方式
    Sql Server 2008R2升级 Sql Server 2012 问题
    第一次ACM
  • 原文地址:https://www.cnblogs.com/kfx2007/p/3428946.html
Copyright © 2011-2022 走看看