Create Dynamic Links With URL Tag In Django

Create Dynamic Links With URL Tag In Django

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 %}

  • url is the tag which operates like a function
  • namedurl is the name of the path to link to
  • timeframe is an argument to pass to that route
  • more than one argument can be included, separated by spaces.
  • 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