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'
  • 相关阅读:
    VMware coding Challenge: Coin Toss Betting
    Lintcode: k Sum II
    Lintcode: Interleaving Positive and Negative Numbers
    Lintcode: Insert Node in a Binary Search Tree
    Amazon OA
    Leetcode: Best Time to Buy and Sell Stock IV
    Leetcode: Reverse Words in a String II
    Leetcode: Repeated DNA Sequence
    Leetcode: Rotate Array
    VMware coding Challenge:Date of Weekday
  • 原文地址:https://www.cnblogs.com/kfx2007/p/3428946.html
Copyright © 2011-2022 走看看