39
Sometimes you want to name views so that you can refer to them by the name rather than by the url. That way, if the url changes in your app, you only need to update the code in one place (the urls.py
module). Existing code, which used the name rather than the url hardcoded, does not need to be updated.
For example, the reverse
utility function accepts this name and returns the url:
from django.urls import reverse
reverse('bar')
If you do not make use of the name, moving a route is cumbersome – you need to find and update the urls throughout all the templates and the code.
28
Imagine that you need to write a URL to refer to your FooView
, then you can write it like
<a href="/foo/">link</a>
But a problem can occur if you later change your mind, and want to use qux/
for this view. So rewriting a URL, could result in a large amount of rewrites. It is also cumbersome if the URL contains parameters. Say you have a URL with a pk
and type
parameter (like foo/<pk>/qux/<type>
), then you need to remember the format, and thus reason about the format, which is cumbersome: “is it /foo/1/qux/2
or /foo/2/qux/1
?”.
So we do not want to write these URL directly, we want to determine these: calculating the URL based on some identifier, and zero or more parameters. By defining a name in a path, we thus first need to define such identifier, and we can define a name for such path.
So now we can in the template use the {% url .. %}
template tag instead, like:
<a href="{% url 'bar' %}">link</a>
Django will then do the math, and replace it with the correct URL. Not only does this save us a headache, the URL is also guaranteed to be correct (given of course the name itself is correct). So if it renders HTML output, we do not need to worry, that we might have written a typo in one of the URLs, since the {% url .. %}
tag will raise an error if it can not find the name, or in case the parameters do not match.
We can do the same when we for example want to redirect to a page. If we have a certain view that redirects to bar
, it looks like:
def redirect_view(request):
return redirect('bar')
and again, we are done. If later the URL changes, or when for example somebody wants to implemented translated URLs (for example you can run a server in English, and one in Russian), then these URLs will have the correct translation.
In case the URL contains a parameter, like for example:
urlpatterns = [
path('foo/<int:pk>/edit',views.FooView,name='bar'),
]
We can use this parameter as well. In the template it looks like:
<a href="{% url 'bar' pk=2 %}">link</a>
or in the view:
def redirect_view(request):
return redirect('bar', pk=2)
How that parameter fits in the URL, is not our problem. Django will find this out itself.
- [Django]-'WSGIRequest' object has no attribute 'user' Django admin
- [Django]-How to query Case-insensitive data in Django ORM?
- [Django]-How to force migrations to a DB if some tables already exist in Django?
4
The above answers did not cater to me as a beginner. Maybe I could explain it in more layman terms.
After adding a url path in the urls file, and defining corresponding view function to deal with it, If we want to access this same url through views in some place else, or maybe in the template file of your html pages, you do that using name and namespace in your code to access it, just like variable names. This helps because defining another url path and/or using direct links, makes the code more difficult to maintain.
For Example:
x=5
xi=x+1
xd=x-1
xf=x
is better than the one below, since if you want to change x
to something else someday, it is just one change away.
x=5
xi=6
xd=4
xf=5
As for how to use it, you could use the above answers or read django URL naming.
- [Django]-Django rest framework lookup_field through OneToOneField
- [Django]-Django's SuspiciousOperation Invalid HTTP_HOST header
- [Django]-Mixin common fields between serializers in Django Rest Framework
3
All above are pretty good answers but i want to try to explain it in much simpler way
My urls.py inside polls app:
urlpatterns = [
path('', views.index, name='index'),
# /polls/5/
# sends the values of question_id to the views
path('<int:question_id>/', views.detail, name='detail'),
# /polls/5/results
path('<int:question_id>/results', views.results, name='results'),
# /polls/5/vote
path('<int:question_id>/vote', views.vote, name='vote'),
]
and a small part of my index.html is:
<a href="{% url 'index' %}">index</a>
<a href="{% url 'detail' question_id=1 %}">detail</a>
<a href="{% url 'results' question_id=1 %}">results</a>
Inside index.html this shows index detail results as links as obvious, but notice here that inside <a>
tag I use url
tag of the Django
The correct format of using url
tag of Django is:
{% url 'NAME OF URL here' any_variables_here %}
NAME OF URL
means the name that we give the name to a URL inside name
argument of path()
that means we only have to use name of the URL inside href
attribute, we now don’t have to use the hectic and complex url everywhere inside our code that’s awesome feature of Django.
And the most important advantage is like if we changed our URL inside the urls.py like:
<int:question_id>/vote
to <int:question_id>/funny_poll/vote
then now you don’t need to worry about changing the url in each and every file wherever you used it before.
This is quite awesome and a Django developer should use this feature.
HaPpY Coding
- [Django]-Determine variable type within django template
- [Django]-Django ManyToMany filter()
- [Django]-OSError: [Errno 18] Invalid cross-device link