Python Django-让中间件与视图/模板通信

Python Django-让中间件与视图/模板通信,python,django,Python,Django,好吧,这可能是一个非常愚蠢的问题,但我对Python/Django还不熟悉,所以我还不能真正理解它的范围概念。现在我正在编写一个类来处理一些东西,我想设置视图和模板可以访问的“全局”变量。“正确”的做法是什么?我考虑过这样做: return HttpResponse (..., mimetype='text/plain') 中间件.py views.py 虽然这是可行的,但我不确定这是“Django方式”还是“Python方式” 因此,我的问题是: 1.这条路对吗? 2.如果这是正确的方法,那

好吧,这可能是一个非常愚蠢的问题,但我对Python/Django还不熟悉,所以我还不能真正理解它的范围概念。现在我正在编写一个类来处理一些东西,我想设置视图和模板可以访问的“全局”变量。“正确”的做法是什么?我考虑过这样做:

return HttpResponse (..., mimetype='text/plain')
中间件.py views.py 虽然这是可行的,但我不确定这是“Django方式”还是“Python方式”

因此,我的问题是:
1.这条路对吗?
2.如果这是正确的方法,那么添加变量的正确方法是什么,这些变量可以在中间件的实际模板中使用?假设我想要评估某个东西,我想要在中间件中将变量
headername
设置为“我的站点名称”,并且我想要能够在所有模板中执行
{{headername}
。按照现在的方式,我必须将
headername
添加到每个视图中的上下文中。有没有办法绕过这个?我在想CakePHP的
$this->set('headername','My Site Name')
3.我使用中间件类作为CakePHP的
beforeFilter
的等价物,它在调用每个视图(或CakePHP中的控制器)之前运行。这样做对吗?
4.完全不相关,但这是一个小问题,将变量内容打印到浏览器ala
print\r
的好方法是什么?假设我想查看传递到视图中的
请求
中的所有内容?
pprint
是答案吗?

1)如果您修改“设置”,即使在请求之间,这也是真正的全局性的。换句话说,如果您需要每个请求都有自己的值,那么并发请求将互相践踏。修改请求对象本身更安全,这是一些常见的Django中间件所做的(例如,Django.contrib.auth.middleware.AuthenticationMiddleware在请求对象上添加对“user”的引用)

2) (编辑2)参见#4,在每个模板中加入一组通用变量可能更适合定制上下文处理器

3) 我不熟悉CakePHP,但是添加一个process_请求中间件绝对是一种很好的Django预处理每个请求的方法

4) 看一下你的医生。如果使用RequestContext,每个模板都会有一个名为“request”的上下文变量,您可以将其转储到模板中。您还可以使用调试上下文处理器并执行类似操作,以便它仅在设置时转储。debug=True:

{% if debug %}
  <!-- {{ request.REQUEST }} -->
{% endif %}
这只是为了明确,您没有返回HTML、XML或其他结构化内容类型

编辑2


刚刚看到问题被更新为一个新的子问题,重新编号的答案。我们使用这样的上下文处理器

def context_myApp_settings(request):
    """Insert some additional information into the template context
    from the settings.
    Specifically, the LOGOUT_URL, MEDIA_URL and BADGES settings.
    """
    from django.conf import settings
    additions = {
        'MEDIA_URL': settings.MEDIA_URL,
        'LOGOUT_URL': settings.LOGOUT_URL,
        'BADGES': settings.BADGES,
        'DJANGO_ROOT': request.META['SCRIPT_NAME'],
    }
    return additions
这里是激活此功能的设置

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
    "myapp. context_myApp_settings",
    )
这将在呈现的每个模板的上下文中提供“全局”信息。这是标准的Django解决方案。有关上下文处理器的更多信息,请参阅


“将变量内容打印到浏览器ala print\r的好方法是什么?”

在视野中?您可以为模板提供
pprint.pformat
字符串,以便进行调试

在日志中?您必须使用Python的
日志记录
模块,并将内容发送到单独的日志文件。对于所有Django实现,使用简单的print语句将内容写入日志的效果并不一致(例如,mod_python会丢失所有stdout和stderr内容)

  • 这不是最好的办法。您可以在请求上而不是在设置上设置my_var。设置为全局设置,并应用于整个站点。您不想为每个请求都修改它。多个请求同时更新/读取变量可能存在并发问题

  • 要访问模板中的request.my_var,您可以执行{{request.my_var}}。要访问模板中的请求变量,必须将django.core.context\u处理器.request添加到模板\u context\u处理器设置中

  • 对。描述请求中间件的其他术语是请求预处理器/过滤器/拦截器


  • 此外,如果您想在模板中为标题使用公共站点名称,您可能需要查看Django Sites应用程序,该应用程序提供一个站点名称变量供您使用。

    +1这正是我们所做的,只有一个例外:我们向请求添加一个dict,然后向该请求添加值。这可以防止您“污染”请求的名称空间,这是不必要的。+1谢谢。网站名称只是我在写问题时想到的第一个例子,我的用例是用于其他方面的。+1,谢谢你的帮助。这个视图只是一个例子,我会有模板和所有好的东西,我只是用它来测试变量是否到达那里,除了是的。再次感谢你的帮助。在我的设置中似乎找不到模板\u上下文\u处理器。py。。。我必须加上它吗?@Paolo Bergantino:有趣。大多数人都是默认的。查看是否使用“django admin startproject”创建项目,然后模板\u上下文\u处理器将不在新创建的settings.py中。当缺少全局_设置值时,当然会使用它,对于Django 1.02,它只是auth、debug、i18n和media。
    def context_myApp_settings(request):
        """Insert some additional information into the template context
        from the settings.
        Specifically, the LOGOUT_URL, MEDIA_URL and BADGES settings.
        """
        from django.conf import settings
        additions = {
            'MEDIA_URL': settings.MEDIA_URL,
            'LOGOUT_URL': settings.LOGOUT_URL,
            'BADGES': settings.BADGES,
            'DJANGO_ROOT': request.META['SCRIPT_NAME'],
        }
        return additions
    
    TEMPLATE_CONTEXT_PROCESSORS = (
        "django.core.context_processors.auth",
        "django.core.context_processors.debug",
        "django.core.context_processors.i18n",
        "django.core.context_processors.media",
        "django.core.context_processors.request",
        "myapp. context_myApp_settings",
        )