Url naming and namespaces

A project's internal links or url references (e.g. <a href='/'>Home Page</a>) tend to be hard-coded, whether it's in view methods to redirect users to certain locations or in templates to provide adequate user navigation. Hard-coding links can present a serious maintenance problem as a project grows, because it leads to links that are difficult to detect and fix. Django offers a way to name urls so it's easy to reference them in view methods and templates.

The most basic technique to name Django urls is to add the name attribute to url definitions in urls.py. Listing 2-16 shows how to name a project's home page, as well as how to reference this url from a view method or template.

Listing 2-16 Django url using name

----------------------------------------------------------------------------
# Definition in coffeehouse/urls.py
path('',TemplateView.as_view(template_name='homepage.html'),name="homepage")

----------------------------------------------------------------------------
# Definition in view method
from django.http import HttpResponsePermanentRedirect
from django.urls import reverse

def method(request):
    ....
    return HttpResponsePermanentRedirect(reverse('homepage'))

----------------------------------------------------------------------------
# Definition in template
<a href="{% url 'homepage' %}">Back to home page</a>

The url definition in listing 2-16 uses the path '' which translates into / or the home page, also known as the root directory. Notice the name attribute with the homepage value. By assigning the url a name you can use this value as a reference in view methods and templates, which means any future changes made to the url path, automatically updates all url definitions in view methods and templates.

Next in listing 2-16 you can see a view method example that redirects control to reverse('homepage'). The Django reverse method attempts to look up a url definition by the given name -- in this case homepage -- and substitutes it accordingly. Similarly, the link sample <a href="{% url 'homepage' %}">Back to home page</a> in listing 2-16 makes use of the Django {% url %} tag, which attempts to look up a url by its first argument -- in this case homepage -- and substitute it accordingly.

This same naming and substitution process is available for more complex url definitions, such as those with url parameters. Listing 2-17 shows the process for a url with parameters.

Listing 2-17. Django url with arguments using name

----------------------------------------------------------------------------
# Definition in coffeehouse/urls.py
path(r'^drinks/<str:drink_name>/',TemplateView.as_view(template_name='drinks/index.html'),name="drink"),

----------------------------------------------------------------------------
# Definition in view method
from django.http import HttpResponsePermanentRedirect
from django.urls import reverse
def method(request):
    ....
    return HttpResponsePermanentRedirect(reverse('drink', args=(drink.name,)))

----------------------------------------------------------------------------
# Definition in template
<a href="{% url 'drink' drink.name %}">Drink on sale</a>
<a href="{% url 'drink' 'latte' %}">Drink on sale</a>

The url definition in listing 2-17 uses a more complex url path with a parameter that translates into urls in the form /drinks/latte/ or /drinks/espresso/. In this case, the url is given the argument name drink_name.