12👍
Well you can enable:
'django.core.context_processors.request',
in your settings.TEMPLATE_CONTEXT_PROCESSORS
block and hook out the referrer but that’s a bit nauseating and could break all over the place.
Most places where you’d want this (eg the edit post page on SO) you have a real object to hook on to (in that example, the post) so you can easily work out what the proper previous page should be.
54👍
Actually it’s go(-1)
.
<input type=button value="Previous Page" onClick="javascript:history.go(-1);">
- [Django]-Using IntellijIdea within an existing virtualenv
- [Django]-How to show processing animation / spinner during ajax request?
- [Django]-Django dynamically filtering with q objects
50👍
This solution worked out for me:
<a href="{{request.META.HTTP_REFERER}}">Go back</a>
But that’s previously adding 'django.core.context_processors.request',
to TEMPLATE_CONTEXT_PROCESSORS
in your project’s settings.
- [Django]-Use get_queryset() method or set queryset variable?
- [Django]-How to specify an IP address with Django test client?
- [Django]-Django: Display Choice Value
16👍
<a href="{{request.META.HTTP_REFERER|escape}}">Back</a>
Here |escape
is used to get out of the " "
string.
- [Django]-How to stop autopep8 not installed messages in Code
- [Django]-Django error: needs to have a value for field "…" before this many-to-many relationship can be used
- [Django]-Switching from MySQL to Cassandra – Pros/Cons?
3👍
You can always use the client side option which is very simple:
<a href="javascript:history.go(1)">Back</a>
- [Django]-Ordering admin.ModelAdmin objects in Django Admin
- [Django]-What is a Django "app" supposed to mean?
- [Django]-How to put comments in Django templates?
3👍
For RESTful links where “Back” usually means going one level higher:
<a href="../"><input type="button" value="Back" class="btn btn-primary" /></a>
- [Django]-Django python date time set to midnight
- [Django]-Blank, Null, and Required in Django Models and ModelForms
- [Django]-How can one change the type of a Django model field from CharField to ForeignKey?
2👍
All Javascript solutions mentioned here as well as the request.META.HTTP_REFERER
solution sometimes work, but both break in the same scenario (and maybe others, too).
I usually have a Cancel button under a form that creates or changes an object. If the user submits the form once and server side validation fails, the user is presented the form again, containing the wrong data. Guess what, request.META.HTTP_REFERER
now points to the URL that displays the form. You can press Cancel a thousand times and will never get back to where the initial edit/create link was.
The only solid solution I can think of is a bit involved, but works for me. If someone knows of a simpler solution, I’d be happy to hear from it. 🙂
The ‘trick’ is to pass the initial HTTP_REFERER into the form and use it from there. So when the form gets POSTed to, it passes the correct, initial referer along.
Here is how I do it:
I created a mixin class for forms that does most of the work:
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", "/")
The form that is used to edit/create the object (usually a ModelForm subclass) might look like this:
class SomeModelForm(FormCancelLinkMixin, forms.ModelForm):
""" Form for creating some model instance. """
class Meta:
model = ModelClass
# ...
The view must pass the current request to the form. For class based views, you can override 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
In the template that displays the form:
<form method="post">
{% csrf token %}
{{ form }}
<input type="submit" value="Save">
<a href="{{ form.get_cancel_link }}">Cancel</a>
</form>
- [Django]-Difference between setattr and object manipulation in python/django
- [Django]-Can't connect to local MySQL server through socket '/tmp/mysql.sock
- [Django]-Django gives Bad Request (400) when DEBUG = False
0👍
For a ‘back’ button in change forms for Django admin what I end up doing is a custom template filter to parse and decode the ‘preserved_filters’ variable in the template. I placed the following on a customized templates/admin/submit_line.html file:
<a href="../{% if original}../{% endif %}?{{ preserved_filters | decode_filter }}">
{% trans "Back" %}
</a>
And then created a custom template filter:
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)
- [Django]-Django rest framework, use different serializers in the same ModelViewSet
- [Django]-Sending images using Http Post
- [Django]-TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
0👍
Using client side solution would be the proper solution.
<a href="javascript:history.go(-1)" class="btn btn-default">Cancel</a>
- [Django]-How can I keep test data after Django tests complete?
- [Django]-How to display the current year in a Django template?
- [Django]-Running django tutorial tests fail – No module named polls.tests