我需要一个按钮,包含在我的Django应用程序的每个页面的标题中,以触发一些全局方法,以切换" mode
"在会话中设置。有两种模式:'预览'并且'发布'。
我提出的一个解决方案:在每个(基于类的)视图中复制post()
方法,以处理模式更改。这似乎很难干。
另一个是从一个超类继承我的所有CBV,或者使用mixin。我想这是一种可能性。
或许更好的解决方案:我已设置context_processor
来处理将模式全局发布到我的模板。这很好用。我还设置了middleware
类process_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
答案 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%}。这样,它很容易添加到任何页面,并保持干燥。