In Django, you typically want to avoid hard coding links into the application. We saw examples of this in the Named URLs and Reverse Function tutorial. The same holds true in Django templates. We do not want to hard code links in the template as they may break if the application changes in the future. The url tag provides a way do dynamically generate links in any Django template. Let’s see how to use this tag now.
Templates Different Than Views
In the views.py file, we created a link dynamically using code that looked like this:
reverse('namedurl', args=[redirect_to])
This does not work in the template, we need a new way to handle creating dynamic links in the template. The way we do this is with the url tag.
url
Returns an absolute path reference (a URL without the domain name) matching a given view and optional parameters. Any special characters in the resulting path will be encoded using iri_to_uri().
Linking To A Path
A prerequisite to using the url tag is that the correct path exists in urls.py. In addition, within the urlconf of urls.py, any route that you want to link to needs to be named. This works out just fine in our case as we do have a named route in urls.py and it is highlighted here:
goals\urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.homepage),
path('<int:timeframe>', views.goals_by_int_timeframe),
path('<str:timeframe>', views.goals_by_timeframe, name='namedurl'),
]
Now we can visit the file where we are going to dynamically generate a link to this route. We can simply build on the example from the prior tutorial.
goals\templates\goals\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
{% for timeframe in timeframes reversed %}
{% if timeframe == 'monthly' %}
<li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|upper }}</a></li>
{% else %}
<li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|capfirst }}</a></li>
{% endif %}
{% endfor %}
</ul>
</body>
</html>
In looking at the highlighted lines just above, we can see two instances of creating a dynamic link in this template. The format is as follows:
{% url ‘namedurl’ timeframe %}
The Generated Links
Looking at what is between the <ul> tags in the template, we see this:
{% for timeframe in timeframes reversed %}
{% if timeframe == 'monthly' %}
<li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|upper }}</a></li>
{% else %}
<li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|capfirst }}</a></li>
{% endif %}
{% endfor %}
The generated markup in the HTML source of this page looks like this:
<li><a href="/goals/monthly">MONTHLY</a></li>
<li><a href="/goals/weekly">Weekly</a></li>
<li><a href="/goals/daily">Daily</a></li>
We can see how the url tag dynamically created those links for us. This is a great tool to make sure the links in your Django application are robust and future-proof as time passes.
Learn More About The URL Tag In Django
- Using Url In Django Templates (stackoverflow.com)
- Team Treehouse Library Url Tag (teamtreehouse.com)
- Django Url Tag And Reverse Function Example (code-learner.com)
- Django Url Template (askpython.com)
- Pycharm Completion And Navigation For Named Url Tags In Django Templates (jetbrains.com)
- How To Add Url Parameters To Django Template Url Tag (stackoverflow.com)
- Creating Urls In Django (overiq.com)
- Sophilabs Django url Template tag (github.com)