代码之家  ›  专栏  ›  技术社区  ›  Paolo Bergantino

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

  •  7
  • Paolo Bergantino  · 技术社区  · 17 年前

    middleware

    中间件.py

    from django.conf import settings
    
    class BeforeFilter(object):
        def process_request(self, request):
            settings.my_var = 'Hello World'
            return None
    

    views.py

    from django.conf import settings
    from django.http import HttpResponse
    
    def myview(request):
        return HttpResponse(settings.my_var)
    


    1.这条路对吗?
    2.如果这是正确的方法,那么添加变量的正确方法是什么,这些变量可以在中间件的实际模板中使用?比如说我想计算一些东西,我想设置一个变量 headername 作为中间件中的“我的站点名”,我希望能够做到这一点 {{ headername }} 每个视图中的上下文。有没有办法绕过这个?我在想一些与CakePHP类似的事情 $this->set('headername','My Site Name');
    3.我将中间件类用作CakePHP的等价物 beforeFilter 在调用每个视图(或CakePHP中的控制器)之前运行。这样做对吗?
    4.完全不相关,但这是一个小问题,将变量的内容打印到浏览器的好方法是什么 print_r request 是否已传递到视图中?是 pprint 答案是什么?

    3 回复  |  直到 17 年前
        1
  •  19
  •   Akbar ibrahim    17 年前
    1. 这不是最好的办法。您可以在请求上而不是在设置上设置my_var。设置为全局设置,并应用于整个站点。您不想为每个请求都修改它。多个请求同时更新/读取变量可能存在并发问题。

    2. {{request.my_var}} . 要访问模板中的请求变量,必须添加 django.core.context_processors.request 给你 模板\u上下文\u处理器 背景

        2
  •  12
  •   S.Lott    17 年前

    这就是我们要做的。我们使用这样的上下文处理器。。。

    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解决方案。看见 http://docs.djangoproject.com/en/dev/ref/templates/api/#ref-templates-api 有关上下文处理器的详细信息。


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

    在视野中?你可以提供一个 pprint.pformat

    在日志中?您必须使用Python的 logging

        3
  •  4
  •   Joe Holloway    17 年前

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

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

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

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

    {% if debug %}
      <!-- {{ request.REQUEST }} -->
    {% endif %}
    

    这将适用于GET和POST,但是如果您只需要其中一个,则可以相应地进行修改。

    还有,我只是仔细看了一下你的观点。我不确定我是否完全理解您通过在响应中返回变量来尝试做什么。如果您真的有这样的用例,您可能还希望如下设置mimetype:

    return HttpResponse (..., mimetype='text/plain')
    

    这只是为了明确,您没有返回HTML、XML或其他结构化内容类型。

    编辑2

    刚刚看到问题被更新为一个新的子问题,重新编号的答案