zoukankan      html  css  js  c++  java
  • template

    D:workspace emplate1 emplate1settings.py
    D:workspace emplate1 emplate1
    D:workspace emplate1

    from django.template import Template, Context

    如果使用的是 Windows 平台,请包含驱动器符号并使用Unix风格的斜杠(/)而不是反斜杠()


    项目下新建templates文件夹专门存放template
    os.path.join(os.path.dirname(__file__), 'templates').replace('\','/')

    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})

    如果不提供第二个参数, render_to_response() 使用一个空字典。


    如果你是个喜欢偷懒的程序员并想让代码看起来更加简明,可以利用 Python 的内建函数 locals() 。它返回的字典对所有局部变量的名称与值进行映射。 因此,前面的视图可以重写成下面这个样子:
    def current_datetime(request):
    current_date = datetime.datetime.now()
    return render_to_response('current_datetime.html', locals())
    在此,我们没有像之前那样手工指定 context 字典,而是传入了 locals() 的值,它囊括了函数执行到该时间点时所定义的一切变量。 因此,我们将 now 变量重命名为 current_date ,因为那才是模板所预期的变量名称。 在本例中, locals() 并没有带来多 大 的改进,但是如果有多个模板变量要界定而你又想偷懒,这种技术可以减少一些键盘输入。
    使用 locals() 时要注意是它将包括 所有 的局部变量,它们可能比你想让模板访问的要多。 在前例中, locals() 还包含了 request 。对此如何取舍取决你的应用程序。


    把所有的模板都存放在一个目录下可能会让事情变得难以掌控。 你可能会考虑把模板存放在你模板目录的子目录中,这非常好。 事实上,我们推荐这样做;一些Django的高级特性(例如将在第十一章讲到的通用视图系统)的缺省约定就是期望使用这种模板布局。
    把模板存放于模板目录的子目录中是件很轻松的事情。 只需在调用 get_template() 时,把子目录名和一条斜杠添加到模板名称之前,如:
    t = get_template('dateapp/current_datetime.html')
    由于 render_to_response() 只是对 get_template() 的简单封装, 你可以对 render_to_response() 的第一个参数做相同处理。
    return render_to_response('dateapp/current_datetime.html', {'current_date': now})
    对子目录树的深度没有限制,你想要多少层都可以。 只要你喜欢,用多少层的子目录都无所谓。
    注意
    Windows用户必须使用斜杠而不是反斜杠。 get_template() 假定的是 Unix 风格的文件名符号约定。

    'django.template.context_processors.debug',
    'django.template.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',


    def auth(request):
    """
    Returns context variables required by apps that use Django's authentication
    system.

    If there is no 'user' attribute in the request, uses AnonymousUser (from
    django.contrib.auth).
    """
    if hasattr(request, 'user'):
    user = request.user
    else:
    from django.contrib.auth.models import AnonymousUser
    user = AnonymousUser()

    return {
    'user': user,
    'perms': PermWrapper(user),
    }


    def messages(request):
    """
    Returns a lazy 'messages' context variable.
    """
    return {
    'messages': get_messages(request),
    'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
    }

    def get_messages(request):
    """
    Returns the message storage on the request if it exists, otherwise returns
    an empty list.
    """
    if hasattr(request, '_messages'):
    return request._messages
    else:
    return []


    def request(request):
    return {'request': request}


    RequestContext和Context处理器
    你需要一段context来解析模板。 一般情况下,这是一个 django.template.Context 的实例,不过在Django中还可以用一个特殊的子类, django.template.RequestContext ,这个用起来稍微有些不同。 RequestContext 默认地在模板context中加入了一些变量,如 HttpRequest 对象或当前登录用户的相关信息。
    当你不想在一系例模板中都明确指定一些相同的变量时,你应该使用 RequestContext 。 例如,考虑这两个视图:
    from django.template import loader, Context

    def view_1(request):
    # ...
    t = loader.get_template('template1.html')
    c = Context({
    'app': 'My app',
    'user': request.user,
    'ip_address': request.META['REMOTE_ADDR'],
    'message': 'I am view 1.'
    })
    return t.render(c)

    def view_2(request):
    # ...
    t = loader.get_template('template2.html')
    c = Context({
    'app': 'My app',
    'user': request.user,
    'ip_address': request.META['REMOTE_ADDR'],
    'message': 'I am the second view.'
    })
    return t.render(c)
    (注意,在这些例子中,我们故意 不 使用 render_to_response() 这个快捷方法,而选择手动载入模板,手动构造context对象然后渲染模板。 是为了能够清晰的说明所有步骤。)
    每个视图都给模板传入了三个相同的变量:app、user和ip_address。 如果我们把这些冗余去掉会不会更好?
    创建 RequestContext 和 context处理器 就是为了解决这个问题。 Context处理器允许你设置一些变量,它们会在每个context中自动被设置好,而不必每次调用 render_to_response() 时都指定。 要点就是,当你渲染模板时,你要用 RequestContext 而不是 Context 。
    最直接的做法是用context处理器来创建一些处理器并传递给 RequestContext 。上面的例子可以用context processors改写如下:
    from django.template import loader, RequestContext

    def custom_proc(request):
    "A context processor that provides 'app', 'user' and 'ip_address'."
    return {
    'app': 'My app',
    'user': request.user,
    'ip_address': request.META['REMOTE_ADDR']
    }

    def view_1(request):
    # ...
    t = loader.get_template('template1.html')
    c = RequestContext(request, {'message': 'I am view 1.'},
    processors=[custom_proc])
    return t.render(c)

    def view_2(request):
    # ...
    t = loader.get_template('template2.html')
    c = RequestContext(request, {'message': 'I am the second view.'},
    processors=[custom_proc])
    return t.render(c)
    我们来通读一下代码:
    首先,我们定义一个函数 custom_proc 。这是一个context处理器,它接收一个 HttpRequest 对象,然后返回一个字典,这个字典中包含了可以在模板context中使用的变量。 它就做了这么多。
    我们在这两个视图函数中用 RequestContext 代替了 Context 。在context对象的构建上有两个不同点。一, RequestContext 的第一个参数需要传递一个 HttpRequest 对象,就是传递给视图函数的第一个参数( request )。二, RequestContext 有一个可选的参数 processors ,这是一个包含context处理器函数的列表或者元组。 在这里,我们传递了我们之前定义的处理器函数 curstom_proc 。
    每个视图的context结构里不再包含 app 、 user 、 ip_address 等变量,因为这些由 custom_proc 函数提供了。
    每个视图 仍然 具有很大的灵活性,可以引入我们需要的任何模板变量。 在这个例子中, message 模板变量在每个视图中都不一样。
    在第四章,我们介绍了 render_to_response() 这个快捷方式,它可以简化调用 loader.get_template() ,然后创建一个 Context 对象,最后再调用模板对象的 render()过程。 为了讲解context处理器底层是如何工作的,在上面的例子中我们没有使用 render_to_response() 。但是建议选择 render_to_response() 作为context的处理器。这就需要用到context_instance参数:
    from django.shortcuts import render_to_response
    from django.template import RequestContext

    def custom_proc(request):
    "A context processor that provides 'app', 'user' and 'ip_address'."
    return {
    'app': 'My app',
    'user': request.user,
    'ip_address': request.META['REMOTE_ADDR']
    }

    def view_1(request):
    # ...
    return render_to_response('template1.html',
    {'message': 'I am view 1.'},
    context_instance=RequestContext(request, processors=[custom_proc]))

    def view_2(request):
    # ...
    return render_to_response('template2.html',
    {'message': 'I am the second view.'},
    context_instance=RequestContext(request, processors=[custom_proc]))
    在这,我们将每个视图的模板渲染代码写成了一个单行。
    虽然这是一种改进,但是,请考虑一下这段代码的简洁性,我们现在不得不承认的是在 另外 一方面有些过分了。 我们以代码冗余(在 processors 调用中)的代价消除了数据上的冗余(我们的模板变量)。 由于你不得不一直键入 processors ,所以使用context处理器并没有减少太多的输入量。
    Django因此提供对 全局 context处理器的支持。 TEMPLATE_CONTEXT_PROCESSORS 指定了哪些context processors总是默认被使用。这样就省去了每次使用 RequestContext 都指定 processors 的麻烦。
    默认情况下, TEMPLATE_CONTEXT_PROCESSORS 设置如下:
    TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    )
    这个设置项是一个可调用函数的元组,其中的每个函数使用了和上文中我们的 custom_proc 相同的接口,它们以request对象作为参数,返回一个会被合并传给context的字典: 接收一个request对象作为参数,返回一个包含了将被合并到context中的项的字典。
    每个处理器将会按照顺序应用。 也就是说如果你在第一个处理器里面向context添加了一个变量,而第二个处理器添加了同样名字的变量,那么第二个将会覆盖第一个。
    Django提供了几个简单的context处理器,有些在默认情况下被启用的。
    django.core.context_processors.auth
    如果 TEMPLATE_CONTEXT_PROCESSORS 包含了这个处理器,那么每个 RequestContext 将包含这些变量:
    user :一个 django.contrib.auth.models.User 实例,描述了当前登录用户(或者一个 AnonymousUser 实例,如果客户端没有登录)。
    messages :一个当前登录用户的消息列表(字符串)。 在后台,对每一个请求,这个变量都调用 request.user.get_and_delete_messages() 方法。 这个方法收集用户的消息然后把它们从数据库中删除。
    perms : django.core.context_processors.PermWrapper 的一个实例,包含了当前登录用户有哪些权限。
    关于users、permissions和messages的更多内容请参考第14章。
    django.core.context_processors.debug
    这个处理器把调试信息发送到模板层。 如果TEMPLATE_CONTEXT_PROCESSORS包含这个处理器,每一个RequestContext将包含这些变量:
    debug :你设置的 DEBUG 的值( True 或 False )。你可以在模板里面用这个变量测试是否处在debug模式下。
    sql_queries :包含类似于 ``{‘sql’: …, ‘time’: `` 的字典的一个列表, 记录了这个请求期间的每个SQL查询以及查询所耗费的时间。 这个列表是按照请求顺序进行排列的。
    System Message: WARNING/2 (<string>, line 315); backlink
    Inline literal start-string without end-string.
    由于调试信息比较敏感,所以这个context处理器只有当同时满足下面两个条件的时候才有效:
    DEBUG 参数设置为 True 。
    请求的ip应该包含在 INTERNAL_IPS 的设置里面。
    细心的读者可能会注意到debug模板变量的值永远不可能为False,因为如果DEBUG是False,那么debug模板变量一开始就不会被RequestContext所包含。
    django.core.context_processors.i18n
    如果这个处理器启用,每个 RequestContext 将包含下面的变量:
    LANGUAGES : LANGUAGES 选项的值。
    LANGUAGE_CODE :如果 request.LANGUAGE_CODE 存在,就等于它;否则,等同于 LANGUAGE_CODE 设置。
    附录E提供了有关这两个设置的更多的信息。
    django.core.context_processors.request
    如果启用这个处理器,每个 RequestContext 将包含变量 request , 也就是当前的 HttpRequest 对象。 注意这个处理器默认是不启用的,你需要激活它。
    如果你发现你的模板需要访问当前的HttpRequest你就需要使用它:
    {{ request.REMOTE_ADDR }}

    写Context处理器的一些建议
    编写处理器的一些建议:
    使每个context处理器完成尽可能小的功能。 使用多个处理器是很容易的,所以你可以根据逻辑块来分解功能以便将来复用。
    要注意 TEMPLATE_CONTEXT_PROCESSORS 里的context processor 将会在基于这个settings.py的每个 模板中有效,所以变量的命名不要和模板的变量冲突。 变量名是大小写敏感的,所以processor的变量全用大写是个不错的主意。
    不论它们存放在哪个物理路径下,只要在你的Python搜索路径中,你就可以在 TEMPLATE_CONTEXT_PROCESSORS 设置里指向它们。 建议你把它们放在应用或者工程目录下名为 context_processors.py 的文件里。

  • 相关阅读:
    微信小程序之相对位置
    SQL中 in 、not in 、exists、not exists 用法和差别
    指令打印程序(通过Socket)
    javaee正则表达式基础和常用表达式
    分析JSON/XML
    Hello2 source analisis(代码分析)
    Analysis Of HTTP
    Servlet Filter详细讲
    Analysis of Web.xml in Hello1 project
    Java annotation (注解)
  • 原文地址:https://www.cnblogs.com/newpython/p/5432601.html
Copyright © 2011-2022 走看看