Django:为所有(基于类的)视图提供全局方法?

时间:2015-06-10 17:20:20

标签: python django django-middleware class-based-views

我需要一个按钮,包含在我的Django应用程序的每个页面的标题中,以触发一些全局方法,以切换" mode"在会话中设置。有两种模式:'预览'并且'发布'。

我提出的一个解决方案:在每个(基于类的)视图中复制post()方法,以处理模式更改。这似乎很难干。

另一个是从一个超类继承我的所有CBV,或者使用mixin。我想这是一种可能性。

或许更好的解决方案:我已设置context_processor来处理将模式全局发布到我的模板。这很好用。我还设置了middlewareprocess_request,理论上可以全局处理POST个请求。但是如何从模板中调用此process_request方法?

我目前正在盯着它。如何切换"预览"和"发布"我的模板中的按钮,并调用中间件?

template.html

<html>
<head></head>
<body>
<header>
    <form method="post">
    {% csrf_token %}
    <!-- button toggle -->
    {% if mode == 'preview' %}
        <button name="mode" value="publish">Publish</button>
    {% else %}
        <button name="mode" value="preview">Preview</button>
    {% endif %}
    </form>
</header>
</body>
</html>

middleware.py

class MyMiddleware(object):
    def process_request(self, request):
        update_mode(request)

def update_mode(request, new_mode=None): # how do I call this from template?
    modes = [
        'preview',
        'publish'
    ]

    # ensure default
    if not request.session.get('mode', None):
        request.session['mode'] = 'preview'

    # set new mode
    if new_mode and new_mode in modes:
        request.session['mode'] = new_mode

context_processor.py

def template_mode(request):
    context = {
        'mode': request.session['mode']
    }
    return context

2 个答案:

答案 0 :(得分:2)

你不打电话&#34;中间件:它根本不是它的工作方式。每次请求都会调用中间件,因此在您的情况下,update_mode函数将始终运行。

更好的解决方案是让包含按钮的表单发布到新URL,该URL调用视图来更新模式。您可以添加一个包含当前URL的隐藏字段 - 您可以从request.path获取 - 并且更新模式视图可以在完成其工作后重定向回该URL。

答案 1 :(得分:1)

我不这样做 - 如何为表单制作模板标签?

在你的templatetags.py中:

def set_session_mode_form():
    return {'session_form': SessionForm()}

register.inclusion)tag("<path-to-your-template>",set_session_mode_form)

然后,您的会话表单将发送到更新所需会话变量的视图。 要使用它,只需在页面上加载标记并使用{%include%}。这样,它很容易添加到任何页面,并保持干燥。