热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

详解Django框架中用context来解析模板的方法

这篇文章主要介绍了详解Django框架中用context来解析模板的方法,Django是重多高人气Python框架中最为著名的一个,需要的朋友可以参考下

你需要一段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 模板变量在每个视图中都不一样。

 为了讲解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 (, 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 设置。

django.core.context_processors.request

如果启用这个处理器,每个 RequestContext 将包含变量 request , 也就是当前的 HttpRequest 对象。 注意这个处理器默认是不启用的,你需要激活它。

如果你发现你的模板需要访问当前的HttpRequest你就需要使用它:

{{ request.REMOTE_ADDR }}



推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • Django + Ansible 主机管理(有源码)
    本文给大家介绍如何利用DjangoAnsible进行Web项目管理。Django介绍一个可以使Web开发工作愉快并且高效的Web开发框架,能够以最小的代价构建和维护高 ... [详细]
  • Django学习笔记之djangodebugtoolbar使用指南
    介绍django-debug-toolbar是一组可配置的面板,可显示有关当前请求响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息。github地址文档地址安装配置1. ... [详细]
  • 第一种<script>$(".eq").on(&qu ... [详细]
  • 本文内容皆为作者原创,如需转载,请注明出处:https:www.cnblogs.comxuexianqip13045462.html1.自定义分页器的拷贝及使用当我们需要使用 ... [详细]
  • 十六.增加一个项目协作留言板功能(二)----- 建立一个任务管理的列表页面
    我们设计一个页面来展示正在处理的任务,该表格可以参照之前基础信息的增删改查。用户通过这个页面对任务进行相应操作。1.在views. ... [详细]
  • 原文:http:blog.linjunhalida.comblogpjaxgithub:https:github.comdefunktjquery-pjax ... [详细]
  • pyecharts 介绍
    一、pyecharts介绍ECharts,一个使用JavaScript实现的开源可视化库,可以流畅的运行在PC和移动设备上,兼容当前绝大部 ... [详细]
  • DRF类视图让你的代码DRY起来
    刚开始写views.py模块的代码,一般都是用def定义的函数视图,不过DRF更推荐使用class定义的类视图,这能让我们的代码更符合DRY(Don'tRepeatYour ... [详细]
  • Django使用模板语言的目的是使前端代码与后端代码分离(解耦)模板语言=html ... [详细]
author-avatar
闪亮登台
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有