{"id":120263,"date":"2024-12-18T01:30:05","date_gmt":"2024-12-18T01:30:05","guid":{"rendered":"\/tutorials\/?p=120263"},"modified":"2024-12-20T12:17:26","modified_gmt":"2024-12-20T12:17:26","slug":"django-url-patterns","status":"publish","type":"post","link":"\/my\/tutorials\/django-url-patterns","title":{"rendered":"Understanding Django URL patterns"},"content":{"rendered":"<p>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.<\/p><p>In this tutorial, we will explain all about Django URL patterns, including how to make one using regular expressions or path converters.<\/p><p>\n\n\n\n\n\n\n<\/p><h2 class=\"wp-block-heading\" id=\"h-what-are-django-url-patterns\">What are Django URL patterns?<\/h2><p>Django URL patterns route a view to a specific address, which users can use to view the content. They are essential for ensuring that <a href=\"\/my\/tutorials\/building-django-views\">Django views<\/a> have a corresponding URL, so when you <a href=\"\/my\/vps\/django-hosting\">host your Django project on a server<\/a>, it is accessible and doesn&rsquo;t return a 404 error.<\/p><p>Let&rsquo;s consider a real-world example to demonstrate how they work. You have a view rendering the content of your <strong>about <\/strong>page. To make it accessible through<strong> domain.tld\/about<\/strong>, create a URL pattern routing the view to <strong>\/about<\/strong>.<\/p><p>Set the URL pattern inside <strong>urls.py<\/strong>, which is located in the same folder as your Django <strong>views.py<\/strong>. This file defines which function in <strong>views.py <\/strong>will trigger when a user sends HTTP requests through the specified URL. <\/p><p>If you want to learn more about using and managing views, check out our Django views article.<\/p><?xml encoding=\"utf-8\" ?><figure class=\"wp-block-image size-large\"><a href=\"\/my\/vps-hosting\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" width=\"1024\" height=\"300\" src=\"https:\/\/www.hostinger.com\/tutorials\/wp-content\/uploads\/sites\/2\/2023\/02\/VPS-hosting-banner-1024x300.png\" alt=\"\" class=\"wp-image-77934\" srcset=\"https:\/\/www.hostinger.com\/my\/tutorials\/wp-content\/uploads\/sites\/45\/2023\/02\/VPS-hosting-banner.png 1024w, https:\/\/www.hostinger.com\/my\/tutorials\/wp-content\/uploads\/sites\/45\/2023\/02\/VPS-hosting-banner-300x88.png 300w, https:\/\/www.hostinger.com\/my\/tutorials\/wp-content\/uploads\/sites\/45\/2023\/02\/VPS-hosting-banner-150x44.png 150w, https:\/\/www.hostinger.com\/my\/tutorials\/wp-content\/uploads\/sites\/45\/2023\/02\/VPS-hosting-banner-768x225.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure><h2 class=\"wp-block-heading\" id=\"h-project-level-vs-app-level-urls\">Project-level vs. app-level URLs<\/h2><p>A complex Django project might consist of multiple smaller applications. For better organization, you can create URL patterns on the project or application level.<\/p><p><strong>Project-level URLs<\/strong><\/p><p>Project-level URLs route requests on a wider scope, such as views for the admin page or between applications. You can define them in <strong>urls.py<\/strong> inside your project root directory next to <strong>settings.py<\/strong>.<\/p><p>For example, if your website has a smaller blog and shop application, your project-level URLs might include <strong>\/admin<\/strong>, <strong>\/blog<\/strong>, and<strong> \/shop<\/strong>.<\/p><p><strong>App-level URLs<\/strong><\/p><p>App-level URLs route views within the same application. For example, if your website has a blog section, the URLs might include <strong>\/blog\/post-id<\/strong>, <strong>\/blog\/archive<\/strong>, or <strong>\/blog\/author-id<\/strong>.<\/p><p>To define app-level URLs, use <strong>urls.py <\/strong>inside your application folder. For example, specify blog-related URLs in <strong>myproject\/blog\/<\/strong>.<\/p><h2 class=\"wp-block-heading\" id=\"h-basic-url-configuration\">Basic URL configuration<\/h2><p>To map a URL pattern to a view, use<strong> urlpatterns<\/strong> and specify the address using the <strong>path()<\/strong> function in the <strong>urls.py <\/strong>file. Before doing so, import the <strong>path<\/strong> module and your <strong>views<\/strong> like so:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from django.urls import path, include\nfrom . import views <\/pre><p>Now, you can map a URL using the following syntax:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">urlpatterns = [ \n   path('url-name\/', views.view_name, name='url_name'),\n]<\/pre><p>The<strong> &lsquo;url-name\/&rsquo;, views.view_name <\/strong>section maps a URL to a specific function in your views. Optionally, you can name this URL pattern by changing the &lsquo;<strong>url_name<\/strong>&rsquo; which we will explain more later.<\/p><p>For example, if you want to create a project-level URL pattern for your <strong>\/archive<\/strong> and <strong>\/disclaimer <\/strong>pages, the code might look as follows:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from django.urls import path, include\nfrom . import views \n\nurlpatterns = [ \n   path('archive', views.archive,),\n   path('disclaimer', views.disclaimer,),\n]<\/pre><h2 class=\"wp-block-heading\" id=\"h-url-routing-with-views\">URL routing with views<\/h2><p>After setting up the URL patterns, create the functions that will run upon receiving user requests. Add them to your application&rsquo;s <strong>views.py<\/strong> file.<\/p><p>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<strong> render<\/strong> module.<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from django.shortcuts import render<\/pre><p>Then, add your functions like so:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def archive(request):\n    return render(request, 'archive.html')\n\ndef disclaimer(request):\n    return render(request, 'disclaimer.html')<\/pre><p>In this code, we define two functions &ndash; <strong>archive<\/strong> and <strong>disclaimer<\/strong>. Both use the <strong>request<\/strong> object to process users&rsquo; HTTP requests and return the <strong>render <\/strong>function to show content from the <a href=\"\/my\/tutorials\/working-with-django-templates\">Django templates<\/a>. <\/p><p>Based on the URL patterns defined in the previous section&rsquo;s code, accessing <strong>domain.tld\/archive<\/strong> will render <strong>archive.html<\/strong>, while <strong>domain.tld\/disclaimer<\/strong> will show the content of <strong>disclaimer.html<\/strong>.<\/p><h2 class=\"wp-block-heading\" id=\"h-dynamic-url-patterns-and-parameters\">Dynamic URL patterns and parameters<\/h2><p>Instead of setting up URL patterns for all pages, you can create a dynamic address that changes automatically based on specific variables.<\/p><p>To do so, you must capture the<strong> URL parameters<\/strong> &ndash; 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.<\/p><p>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&rsquo;ll explain their differences in the later section.<\/p><p>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. <\/p><p><strong>Integer or int:<\/strong><\/p><p>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:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">path('article\/&lt;int:id&gt;\/', views.article_detail)<\/pre><p>The example matches URLs like <strong>article\/10<\/strong> or <strong>article\/324<\/strong>.<\/p><p><strong>String or str:<\/strong><\/p><p>The string converter captures a sequence of any characters, excluding an empty space and the forward-slash (<strong>\/<\/strong>) separator. Here&rsquo;s a code example:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">path('user\/&lt;str:username&gt;\/', views.user_profile)<\/pre><p>The pattern will match URLs like<strong> user\/hostinger <\/strong>or <strong>user\/vpsisfun<\/strong>.<\/p><p><strong>Slugs or slug:<\/strong><\/p><p>Slug converters capture the permalinks of posts, which are strings of lowercase characters separated by hyphens or underscores. The code looks as follows:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">path('post\/&lt;slug:slug&gt;\/', views.blog_post)<\/pre><p>The above example matches URLs such as<strong> user\/post-permalink<\/strong> or <strong>user\/first_post<\/strong>.<\/p><p><strong>UUID or uuid:<\/strong><\/p><p>The UUID converter captures a universal unique identifier (UUID) string consisting of 32-character hexadecimal values. Here&rsquo;s an example:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">path('order\/&lt;uuid:id&gt;\/', views.order_detail)<\/pre><p>The code will match URLs like<strong> \/order\/123e4567-e89b-12d3-a456-426614174000\/<\/strong>. This converter is useful for mapping automatically generated IDs, such as invoices or order numbers.<\/p><p><strong>Path or path:<\/strong><\/p><p>Use <strong>path: <\/strong>to capture strings consisting of characters, including the forward slash (<strong>\/<\/strong>) separator. The code looks as follows:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">path('files\/&lt;path:file_path&gt;\/', views.file_detail)<\/pre><p>In the example, the pattern matches URLs like <strong>files\/images\/logo.png<\/strong>.<\/p><p><strong>Multiple converters<\/strong><\/p><p>You can combine path converters in the same URL pattern to capture multiple dynamic values. Here&rsquo;s an example:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">urlpatterns = [\n    path('product\/&lt;slug:category&gt;\/&lt;int:id&gt;\/', views.product_detail),\n]<\/pre><p>The code snippet captures two parameters &ndash; slug, which is the product category, and the ID in integer. It means the pattern will match URLs like <strong>product\/shoes-and-sandals\/23<\/strong>.<\/p><h2 class=\"wp-block-heading\" id=\"h-named-url-patterns\">Named URL patterns<\/h2><p>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.<\/p><p>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 <strong>urls.py<\/strong>, which is less prone to human error.<\/p><p>For example, we&rsquo;ll create a URL pattern called <strong>posted<\/strong>:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">patternsurl=[\n    path('post\/&lt;int:id&gt;\/', views.postid, name='postid'),\n]<\/pre><p>To generate the URL pattern based on its name, use the <strong>reverse() f<\/strong>unction. It enables the name to resolve and include dynamic values, which the path converters represent. Your <strong>views <\/strong>code might look like this:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from django.shortcuts import render, get_object_or_404\nfrom django.urls import reverse\nfrom .models import Post  # if you have a Post model\n\ndef postid(request, id):\n    post = get_object_or_404(Post, id=id)\n    post_url = reverse('postid', kwargs={'id': post.id})\n    return render(request, 'post_detail.html', {'post': post, 'post_url': post_url})<\/pre><p>The<strong> reverse() <\/strong>function calls the URL named <strong>postid<\/strong>, which we previously set in<strong> urls.py.<\/strong> Then, <strong>kwargs<\/strong> pulls the value of the current post ID, passing it to the path converter placeholders.<\/p><p>Once we have the URL pattern,<strong> the render()<\/strong> function processes the content, generating the <strong>post_detail.html <\/strong>template to users.<\/p><h2 class=\"wp-block-heading\" id=\"h-regular-expressions-vs-path-converters\">Regular expressions vs. path converters<\/h2><p>Django used regular expressions (regex) to create placeholders for dynamic URL parameters. However, it introduces path converters as a replacement in the newer versions.<\/p><p>Regex uses a string of characters arranged in a particular syntax to match the data pattern. For example, you can create a <strong>post\/id<\/strong> URL pattern using this path converter:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">'post\/&lt;int:id&gt;\/'<\/pre><p>However, your pattern might look as follows using regex:<\/p><pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">r'^post\/(?P&lt;id&gt;\\d+)\/<\/pre><p>Here&rsquo;s the comparison between regex and path converters in several aspects:<\/p><ul class=\"wp-block-list\">\n<li><strong>Flexibility<\/strong>. Regex is more flexible than path converters since its syntax allows for more character combinations and pattern matching.<\/li>\n\n\n\n<li><strong>Ease of use<\/strong>. Path converters are shorter and predetermined, making them easier to use than regex.<\/li>\n\n\n\n<li><strong>Error handling<\/strong>. Since path converters are easier to read and write, maintaining them is simpler than regex.<\/li>\n\n\n\n<li><strong>Performance<\/strong>. Regex&rsquo; syntax can be complicated, making the pattern-matching process slower. <\/li>\n<\/ul><h2 class=\"wp-block-heading\" id=\"h-conclusion\">Conclusion<\/h2><p>In Django, URL patterns map views to a specific web address, which users can use to access particular content. For example, you can set <strong>domain.tld\/blog\/<\/strong> to render the blog page of your website.<\/p><p>You can set URL patterns on the project or app level. Those on the project level map central and main pages, like <strong>\/admin<\/strong>. Meanwhile, the app-level ones route views within the same applications, such as different posts within <strong>\/blog<\/strong>.<\/p><p>To create a URL pattern, add the address and the views you want to connect inside the<strong> path()<\/strong> function of <strong>urls.py<\/strong>. Then, in <strong>views.py<\/strong>, define the functions that will trigger when users access the URL, which can render a template or return a message.<\/p><p>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. <\/p><h2 class=\"wp-block-heading\" id=\"h-django-url-pattern-faq\">Django URL pattern FAQ<\/h2><div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1734484102205\"><h3 class=\"schema-faq-question\">How do I create a URL pattern in Django?<\/h3> <p class=\"schema-faq-answer\">To create a URL pattern in Django, create a <strong>urls.py<\/strong> file inside your project or application folders. Then, import<strong> views <\/strong>and the <strong>pat<\/strong>h module. List your URL patterns inside<strong> patternsurl<\/strong>, each with this path function syntax: <strong> path(&lsquo;url-name\/&rsquo;, views.view_name, name=&rsquo;url_name&rsquo;)<\/strong>.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1734484113023\"><h3 class=\"schema-faq-question\">How do I include multiple URL patterns?<\/h3> <p class=\"schema-faq-answer\">To include multiple URL patterns, simply list them inside your <strong>urls.py<\/strong> file&rsquo;s <strong>patternsurl<\/strong>, separated using a comma. Note that each pattern must use the<strong> path() <\/strong>function. If you will use multiple patterns, we recommend naming them for reusability.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1734484162408\"><h3 class=\"schema-faq-question\">How can I reverse a URL in Django?<\/h3> <p class=\"schema-faq-answer\">To reverse a named URL pattern, use the<strong> reverse()<\/strong> function in your views. If you use URL parameters to load values dynamically, add <strong>kwargs<\/strong> to pull the data and pass it to the placeholder.<\/p> <\/div> <\/div>\n","protected":false},"excerpt":{"rendered":"<p>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 [&#8230;]<\/p>\n<p><a class=\"btn btn-secondary understrap-read-more-link\" href=\"\/my\/tutorials\/django-url-patterns\">Read More&#8230;<\/a><\/p>\n","protected":false},"author":337,"featured_media":120144,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Django URL patterns: Understanding dynamic URL routing","rank_math_description":"Learn how to set up Django URL patterns, manage routing efficiently, and apply best practices for project and app-level configurations","rank_math_focus_keyword":"django url patterns","footnotes":""},"categories":[22641,22639],"tags":[],"class_list":["post-120263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pre-installed-applications","category-vps"],"hreflangs":[{"locale":"en-US","link":"https:\/\/www.hostinger.com\/tutorials\/django-url-patterns","default":0},{"locale":"en-UK","link":"https:\/\/www.hostinger.com\/uk\/tutorials\/django-url-patterns","default":0},{"locale":"en-MY","link":"https:\/\/www.hostinger.com\/my\/tutorials\/django-url-patterns","default":0},{"locale":"en-PH","link":"https:\/\/www.hostinger.com\/ph\/tutorials\/django-url-patterns","default":0},{"locale":"en-IN","link":"https:\/\/www.hostinger.com\/in\/tutorials\/django-url-patterns","default":0},{"locale":"en-CA","link":"https:\/\/www.hostinger.com\/ca\/tutorials\/django-url-patterns","default":0},{"locale":"en-AU","link":"https:\/\/www.hostinger.com\/au\/tutorials\/django-url-patterns","default":0},{"locale":"en-NG","link":"https:\/\/www.hostinger.com\/ng\/tutorials\/django-url-patterns","default":0}],"_links":{"self":[{"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/posts\/120263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/users\/337"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/comments?post=120263"}],"version-history":[{"count":4,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/posts\/120263\/revisions"}],"predecessor-version":[{"id":120606,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/posts\/120263\/revisions\/120606"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/media\/120144"}],"wp:attachment":[{"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/media?parent=120263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/categories?post=120263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hostinger.com\/my\/tutorials\/wp-json\/wp\/v2\/tags?post=120263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}