我正在使用Django,我想知道是否有一种简单的方法可以使用模板系统创建到上一页的“后退”链接。
我认为在最坏的情况下,我可以从视图函数中的请求对象获取此信息,并将其传递给模板呈现方法,但我希望我能以某种方式避免所有这些样板代码。
我已经检查了Django模板文档,但我没有看到任何明确提到这一点的内容。
答案 0 :(得分:30)
实际上是go(-1)
。
<input type=button value="Previous Page" onClick="javascript:history.go(-1);">
答案 1 :(得分:21)
这个解决方案适合我:
<a href="{{request.META.HTTP_REFERER}}">Go back</a>
但之前在项目设置中将'django.core.context_processors.request',
添加到TEMPLATE_CONTEXT_PROCESSORS
。
答案 2 :(得分:12)
你可以启用:
'django.core.context_processors.request',
在你的settings.TEMPLATE_CONTEXT_PROCESSORS
区块中并挂出引荐来源,但这有点令人作呕,可能会破坏所有地方。
大多数你想要的地方(例如SO上的编辑帖子页面)你有一个真实的对象可以挂钩(在那个例子中,帖子),这样你就可以很容易地找出正确的上一页应该是什么
答案 3 :(得分:1)
<a href="{{request.META.HTTP_REFERER|escape}}">Back</a>
|escape
退出&#34;&#34; stringage
答案 4 :(得分:0)
您始终可以使用非常简单的客户端选项:
<a href="javascript:history.go(1)">Back</a>
答案 5 :(得分:0)
对于Django管理员更改表单中的“后退”按钮,我最终要做的是一个自定义模板过滤器,用于解析和解码模板中的“preserved_filters”变量。我将以下内容放在自定义的templates / admin / submit_line.html文件中:
<a href="../{% if original}../{% endif %}?{{ preserved_filters | decode_filter }}">
{% trans "Back" %}
</a>
然后创建了自定义模板过滤器:
from urllib.parse import unquote
from django import template
def decode_filter(variable):
if variable.startswith('_changelist_filters='):
return unquote(variable[20:])
return variable
register = template.Library()
register.filter('decode_filter', decode_filter)
答案 6 :(得分:0)
使用客户端解决方案将是正确的解决方案。
<a href="javascript:history.go(-1)" class="btn btn-default">Cancel</a>
答案 7 :(得分:0)
对于RESTful链接,其中“返回”通常意味着往上一级:
WebView(
initialUrl: ur,
javascriptMode: JavascriptMode.unrestricted,)
答案 8 :(得分:0)
此处提到的所有 Javascript 解决方案以及 request.META.HTTP_REFERER
解决方案有时都有效,但两者都在相同的情况下(也可能在其他情况下也有问题)。
我通常在创建或更改对象的表单下有一个取消按钮。如果用户提交一次表单并且服务器端验证失败,则会再次向用户显示包含错误数据的表单。猜猜看,request.META.HTTP_REFERER
现在指向显示表单的 URL。您可以按一千次取消,并且永远不会回到最初的编辑/创建链接所在的位置。
我能想到的唯一可靠的解决方案有点复杂,但对我有用。如果有人知道一个更简单的解决方案,我很高兴收到它。 :-) “技巧”是将初始 HTTP_REFERER 传递到表单中并从那里使用它。因此,当表单被 POST 到时,它会传递正确的初始引用。
我是这样做的:
我为完成大部分工作的表单创建了一个 mixin 类:
from django import forms
from django.utils.http import url_has_allowed_host_and_scheme
class FormCancelLinkMixin(forms.Form):
""" Mixin class that provides a proper Cancel button link. """
cancel_link = forms.fields.CharField(widget=forms.HiddenInput())
def __init__(self, *args, **kwargs):
"""
Override to pop 'request' from kwargs.
"""
self.request = kwargs.pop("request")
initial = kwargs.pop("initial", {})
# set initial value of 'cancel_link' to the referer
initial["cancel_link"] = self.request.META.get("HTTP_REFERER", "")
kwargs["initial"] = initial
super().__init__(*args, **kwargs)
def get_cancel_link(self):
"""
Return correct URL for cancelling the form.
If the form has been submitted, the HTTP_REFERER in request.meta points to
the view that handles the form, not the view the user initially came from.
In this case, we use the value of the 'cancel_link' field.
Returns:
A safe URL to go back to, should the user cancel the form.
"""
if self.is_bound:
url = self.cleaned_data["cancel_link"]
# prevent open redirects
if url_has_allowed_host_and_scheme(url, self.request.get_host()):
return url
# fallback to current referer, then root URL
return self.request.META.get("HTTP_REFERER", "/")
用于编辑/创建对象的表单(通常是 ModelForm 子类)可能如下所示:
class SomeModelForm(FormCancelLinkMixin, forms.ModelForm):
""" Form for creating some model instance. """
class Meta:
model = ModelClass
# ...
视图必须将当前请求传递给表单。对于基于类的视图,您可以覆盖 get_form_kwargs()
:
class SomeModelCreateView(CreateView):
model = SomeModelClass
form_class = SomeModelForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
return kwargs
在显示表单的模板中:
<form method="post">
{% csrf token %}
{{ form }}
<input type="submit" value="Save">
<a href="{{ form.get_cancel_link }}">Cancel</a>
</form>