Understanding Django URL patterns

Django URL patterns map views to specific web addresses. In practice, they enable users to access different content using their corresponding URLs. Meanwhile, URL patterns help developers handle various HTTP requests more efficiently since you can easily set the route.

In this tutorial, we will explain all about Django URL patterns, including how to make one using regular expressions or path converters.

What are Django URL patterns?

URL patterns route a view to a specific address, which users can use to view the content. They ensure each view has a corresponding URL so when you host your Django project on a server, it is accessible and doesn’t return a 404 error.

Let’s consider a real-world example to demonstrate how they work. You have a view rendering the content of your about page. To make it accessible through domain.tld/about, create a URL pattern routing the view to /about.

Set the URL pattern inside urls.py, which is located in the same folder as your Django views.py. This file defines which function in views.py will trigger when a user sends HTTP requests through the specified URL.

Project-level vs. app-level URLs

A complex Django project might consist of multiple smaller applications. For better organization, you can create URL patterns on the project or application level.

Project-level URLs

Project-level URLs route requests on a wider scope, such as views for the admin page or between applications. You can define them in urls.py inside your project root directory next to settings.py.

For example, if your website has a smaller blog and shop application, your project-level URLs might include /admin, /blog, and /shop.

App-level URLs

App-level URLs route views within the same application. For example, if your website has a blog section, the URLs might include /blog/post-id, /blog/archive, or /blog/author-id.

To define app-level URLs, use urls.py inside your application folder. For example, specify blog-related URLs in myproject/blog/.

Basic URL configuration

To map a URL pattern to a view, use urlpatterns and specify the address using the path() function in the urls.py file. Before doing so, import the path module and your views like so:

from django.urls import path, include
from . import views 

Now, you can map a URL using the following syntax:

urlpatterns = [ 
   path('url-name/', views.view_name, name='url_name'),
]

The ‘url-name/’, views.view_name section maps a URL to a specific function in your views. Optionally, you can name this URL pattern by changing the ‘url_name’ which we will explain more later.

For example, if you want to create a project-level URL pattern for your /archive and /disclaimer pages, the code might look as follows:

from django.urls import path, include
from . import views 

urlpatterns = [ 
   path('archive', views.archive,),
   path('disclaimer', views.disclaimer,),
]

URL routing with views

After setting up the URL patterns, create the functions that will run upon receiving user requests. Add them to your application’s views.py file.

You can define functions to give various responses, but for this tutorial, we will show you how to render a specific page template. Begin by importing the render module.

from django.shortcuts import render

Then, add your functions like so:

def archive(request):
    return render(request, 'archive.html')

def disclaimer(request):
    return render(request, 'disclaimer.html')

In this code, we define two functions – archive and disclaimer. Both use the request object to process users’ HTTP requests and return the render function to show content from the Django templates.

Based on the URL patterns defined in the previous section’s code, accessing domain.tld/archive will render archive.html, while domain.tld/disclaimer will show the content of disclaimer.html.

Dynamic URL patterns and parameters

Instead of setting up URL patterns for all pages, you can create a dynamic address that changes automatically based on specific variables.

To do so, you must capture the URL parameters – values in the web address that change depending on the content the user accesses. For example, posts in a blog use different IDs in their URLs.

You can capture the dynamic values using regular expressions and path converters. However, Modern Django recommends path converters since regular expressions are more prone to error. We’ll explain their differences in the later section.

The step to map a dynamic URL pattern is the same as the static one. The difference is that you add the path converters to the URL part that will change its value. Here are some of the most used ones.

Integer or int:

The integer path converter captures numbers from the URL, which is useful for mapping addresses to pages like post IDs. The code looks like this:

path('article/<int:id>/', views.article_detail)

The example matches URLs like article/10 or article/324.

String or str:

The string converter captures a sequence of any characters, excluding an empty space and the forward-slash (/) separator. Here’s a code example:

path('user/<str:username>/', views.user_profile)

The pattern will match URLs like user/hostinger or user/vpsisfun.

Slugs or slug:

Slug converters capture the permalinks of posts, which are strings of lowercase characters separated by hyphens or underscores. The code looks as follows:

path('post/<slug:slug>/', views.blog_post)

The above example matches URLs such as user/post-permalink or user/first_post.

UUID or uuid:

The UUID converter captures a universal unique identifier (UUID) string consisting of 32-character hexadecimal values. Here’s an example:

path('order/<uuid:id>/', views.order_detail)

The code will match URLs like /order/123e4567-e89b-12d3-a456-426614174000/. This converter is useful for mapping automatically generated IDs, such as invoices or order numbers.

Path or path:

Use path: to capture strings consisting of characters, including the forward slash (/) separator. The code looks as follows:

path('files/<path:file_path>/', views.file_detail)

In the example, the pattern matches URLs like files/images/logo.png.

Multiple converters

You can combine path converters in the same URL pattern to capture multiple dynamic values. Here’s an example:

urlpatterns = [
    path('product/<slug:category>/<int:id>/', views.product_detail),
]

The code snippet captures two parameters – slug, which is the product category, and the ID in integer. It means the pattern will match URLs like product/shoes-and-sandals/23.

Named URL patterns

You can name your URL patterns to make it easier to reuse without having to rewrite the full address from scratch. In addition to improving code maintainability, doing so helps minimize issues.

If you hardcode your URL patterns in multiple files like templates and views, you must modify them individually. Conversely, you only need to update named patterns on your urls.py, which is less prone to human error.

For example, we’ll create a URL pattern called posted:

patternsurl=[
    path('post/<int:id>/', views.postid, name='postid'),
]

To generate the URL pattern based on its name, use the reverse() function. It enables the name to resolve and include dynamic values, which the path converters represent. Your views code might look like this:

from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from .models import Post  # assuming you have a Post model

def postid(request, id):
    post = get_object_or_404(Post, id=id)
    post_url = reverse('postid', kwargs={'id': post.id})
    return render(request, 'post_detail.html', {'post': post, 'post_url': post_url})

The reverse() function calls the URL named postid, which we previously set in urls.py. Then, kwargs pulls the value of the current post ID, passing it to the path converter placeholders.

Once we have the URL pattern, the render() function processes the content, generating the post_detail.html template to users.

Regular expressions vs. path converters

Django used regular expressions (regex) to create placeholders for dynamic URL parameters. However, it introduces path converters as a replacement in the newer versions.

Regex uses a string of characters arranged in a particular syntax to match the data pattern. For example, you can create a post/id URL pattern using this path converter:

'post/<int:id>/'

However, your pattern might look as follows using regex:

r'^post/(?P<id>\d+)/

Here’s the comparison between regex and path converters in several aspects:

  • Flexibility. Regex is more flexible than path converters since its syntax allows for more character combinations and pattern matching.
  • Ease of use. Path converters are shorter and predetermined, making them easier to use than regex.
  • Error handling. Since path converters are easier to read and write, maintaining them is simpler than regex.
  • Performance. Regex’ syntax can be complicated, making the pattern-matching process slower.

Conclusion

In Django, URL patterns map views to a specific web address, which users can use to access particular content. For example, you can set domain.tld/blog/ to render the blog page of your website.

You can set URL patterns on the project or app level. Those on the project level map central and main pages, like /admin. Meanwhile, the app-level ones route views within the same applications, such as different posts within /blog.

To create a URL pattern, add the address and the views you want to connect inside the path() function of urls.py. Then, in views.py, define the functions that will trigger when users access the URL, which can render a template or return a message.

A part of your URL pattern can change dynamically using the path converters, which is useful for mapping pages with different IDs. You can also name your URL patterns and reverse them in your views to improve maintainability.

Django URL pattern FAQ

How do I create a URL pattern in Django?

To create a URL pattern in Django, create a urls.py file inside your project or application folders. Then, import views and the path module. List your URL patterns inside patternsurl, each with this path function syntax: path(‘url-name/’, views.view_name, name=’url_name’).

How do I include multiple URL patterns?

To include multiple URL patterns, simply list them inside your urls.py file’s patternsurl, separated using a comma. Note that each pattern must use the path() function. If you will use multiple patterns, we recommend naming them for reusability.

How can I reverse a URL in Django?

To reverse a named URL pattern, use the reverse() function in your views. If you use URL parameters to load values dynamically, add kwargs to pull the data and pass it to the placeholder.

Author
The author

Aris Sentika

Aris is a Content Writer specializing in Linux and WordPress development. He has a passion for networking, front-end web development, and server administration. By combining his IT and writing experience, Aris creates content that helps people easily understand complex technical topics to start their online journey. Follow him on LinkedIn.

Author
The Co-author

Andzelika D.

Andzelika is a Content Writer and Editor with over 5 years of experience in the digital marketing industry. With passion for technology and the art of the written word, she loves to combine the two worlds and produce actionable content.