What Is Reverse in Django
What Is Reverse in Django
When I read django code sometimes, I see in some templates reverse(). I am not quite sure
what this is but it is used together with HttpResponseRedirect. How and when is this
reverse() supposed to be used?
lakesh asked
23.8k ● 54 ● 149 ● 241 Jun 28 '12 at 9:26
21 Given a url pattern, Django uses url() to pick the right view and generate a page. That is,
url--> view name . But sometimes, like when redirecting, you need to go in the reverse direction and
give Django the name of a view, and Django generates the appropriate url. In other words,
view name --> url . That is, reverse() (it's the reverse of the url function). It might seem more
transparent to just call it generateUrlFromViewName but that's too long and probably not general
enough: docs.djangoproject.com/en/dev/topics/http/urls/… – eric Aug 21 '17 at 13:09
3 @neuronet Great explanation, thanks. This name seemed (and seems) particularly non-intuitive to me,
which I hold to be a grave sin. Who doesn't hate unnecessary obfuscation? – mike rodent Jan 6 '18 at
12:48
add a comment
7 Answers order by votes
<!-- django >= 1.5 or with {% load url from future %} in your template
-->
<a href="{% url 'url_name' %}">link which calls some_view</a>
Now say you want to do something similar in your views.py - e.g. you are handling
some other url (not /foo/) in some other view (not some_view) and you want to
redirect the user to /foo/ (often the case on successful form submission).
return HttpResponseRedirect('/foo/')
But what if you want to change the url in future? You'd have to update your urls.py
and all references to it in your code. This violates DRY (Don't Repeat Yourself), the
whole idea of editing one place only, which is something to strive for.
Instead, you can say:
This means that you refer to the url only by its name attribute - if you want to change
the url itself or the view it refers to you can do this by editing one place only -
urls.py.
scytale answered
9,194 ● 3 ● 24 ● 42 Jun 28 '12 at 9:43
daaawx edited
1,353 ● 1 ● 10 ● 12 May 3 '19 at 7:22
2 FYI, {{ url 'url_name' }} should be {% url url_name %} in Django 1.4 or earlier. This will be
changing in the next Django release (1.5) and should then be {% url 'url_name' %} . The docs for the
url templatetag give some good info if you scroll down a bit to the "forwards compatibility" section –
j_syk Jun 28 '12 at 14:58
1 j_syk thanks - i've been doing @load url from future@ since 1.3 came out and forgot that it's not yet the
default. I'll update my answer so it doesn't trip up the inexperienced. – scytale Jun 28 '12 at 15:58
1 fixed - I think it's considered totally acceptable for you to edit dumb typos in other people's answers
yourself so if you see more just jump in :-) – scytale Jun 28 '12 at 20:08
2 One of the most subtle answers one could find on this site. – Manas Chaturvedi Jul 20 '15 at 23:09
1 ">>>but what if you want to change the url in future", These kinds of subtleties that are useful on
.0001% of the time and the solution is shipped like a useful feature, and people use it as if they are 'best
practices' and leave the mess. TBH if when one changes the urls in future you just do a global find-
replace. Even this solution(use url_name) is prone to the problem of 'what if you want to change the
url_name in future?' Been coding in Django for over 5 years and yet to meet the need for url_reverse .
The best way to deal with these kinds of oddities is to refuse to use them. – nehem Nov 13 '17 at 4:49
This is an old question, but here is something that might help someone.
9
From the official docs:
Django provides tools for performing URL reversing that match the different layers
where URLs are needed: In templates: Using the url template tag. In Python code:
Using the reverse() function. In higher level code related to handling of URLs of
Django model instances: The get_absolute_url() method.
OP specifically mentioned that he read the docs, he needed explanation, not just copy/paste from the
docs. – RusI Jan 3 at 7:15
add a comment
The function supports the dry principle - ensuring that you don't hard code urls
4 throughout your app. A url should be defined in one place, and only one place - your
url conf. After that you're really just referencing that info.
Use reverse() to give you the url of a page, given either the path to the view, or the
page_name parameter from your url conf. You would use it in cases where it doesn't
make sense to do it in the template with {% url 'my-page' %}.
There are lots of possible places you might use this functionality. One place I've
found I use it is when redirecting users in a view (often after the successful
processing of a form)-
return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))
Existing answers did a great job at explaining the what of this reverse() function in
4 Django.
However, I'd hoped that my answer shed a different light at the why: why use
reverse() in place of other more straightforward, arguably more pythonic
approaches in template-view binding, and what are some legitimate reasons for the
popularity of this "redirect via reverse() pattern" in Django routing logic.
One key benefit is the reverse construction of a url, as others have mentioned. Just
like how you would use {% url "profile" profile.id %} to generate the url from
your app's url configuration file: e.g. path('<int:profile.id>/profile',
views.profile, name="profile").
But as the OP have noted, the use of reverse() is also commonly combined with the
use of HttpResponseRedirect. But why?
I am not quite sure what this is but it is used together with HttpResponseRedirect.
How and when is this reverse() supposed to be used?
app_name = 'polls'
urlpatterns = [
path('<int:question_id>/results/', views.results, name='polls-resu
lts'),
path('<int:question_id>/vote/', views.vote, name='polls-vote')
]
In the vote() function, the code in our else block uses reverse along with
HttpResponseRedirect in the following pattern:
HttpResponseRedirect(reverse('polls:polls-results',
args=(question.id)
This first and foremost, means we don't have to hardcode the URL (consistent with
the DRY principle) but more crucially, reverse() provides an elegant way to construct
URL strings by handling values unpacked from the arguments (args=(question.id)
is handled by URLConfig). Supposed question has an attribute id which contains the
value 5, the URL constructed from the reverse() would then be:
'/polls/5/results/'
def index(request):
return render(request, 'polls/index.html')
But in many legitimate cases of redirection, we typically care about constructing the
URL from a list of parameters. These include cases such as:
HTML form submission through POST request
User login post-validation
Reset password through JSON web tokens
Most of these involve some form of redirection, and a URL constructed through a set
of parameters. Hope this adds to the already helpful thread of answers!
onlyphantom answered
3,342 ● 2 ● 21 ● 36 Apr 6 '19 at 9:48
The reverse() is used to adhere the django DRY principle i.e if you change the url in
1 future then you can reference that url using reverse(urlname).
AEROCODE answered
36 ● 1 ● 4 Dec 2 '14 at 17:53
The existing answers are quite clear. Just in case you do not know why it is called
1 reverse: It takes an input of a url name and gives the actual url, which is reverse to
having a url first and then give it a name.
Just learning Django from a tutorial (Django Girls). It's a steep learning curve. I think this function's name
is dreadful: "reserve" without any qualification VERY STRONGLY suggests reserving a list or string,
which obviously has nothing whatsoever to do with it. – mike rodent Nov 21 '19 at 13:52
add a comment
Your Answer
Body
Add picture
Log in
OR
Name
By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy
meta chat tour help blog privacy policy legal contact us full site
2020 Stack Exchange, Inc. user contributions under cc by-sa 4.0.