← Back to Django Course | Chapter 2: Apps, URLs & Views | Lesson 7 of 10

Including App-Level URLs

include() lets the main map hand off a whole section to a smaller, app-specific map, so each app looks after its own street instead of one giant map for the whole city.

Splitting URLs Per App

Instead of listing every route for every app in one root urls.py, each app defines its own urls.py, and the project's root urls.py uses include() to delegate a URL prefix to it.

Example: Splitting URLs Per App

Instead of listing every route for every app in one root urls.py, each app defines its own urls.py, and the project's root urls.py uses include() to delegate a URL prefix to it.

markup
# myproject/urls.py
from django.urls import path, include

urlpatterns = [
    path('blog/', include('blog.urls')),
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

The App's Own urls.py

Inside the app, urls.py defines urlpatterns exactly like a root URLconf, except its paths are relative to the prefix used in the include() call above.

Example: The App's Own urls.py

Inside the app, urls.py defines urlpatterns exactly like a root URLconf, except its paths are relative to the prefix used in the include() call above.

markup
# blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.post_list, name='post_list'),
    path('<int:pk>/', views.post_detail, name='post_detail'),
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Namespacing with app_name

Setting app_name in the app's urls.py lets you reference its routes unambiguously elsewhere, e.g. reverse('blog:post_detail'), even if another app also has a URL named post_detail.

Example: Namespacing with app_name

Setting app_name in the app's urls.py lets you reference its routes unambiguously elsewhere, e.g. reverse('blog:post_detail'), even if another app also has a URL named post_detail.

markup
# blog/urls.py
app_name = 'blog'

urlpatterns = [
    path('<int:pk>/', views.post_detail, name='post_detail'),
]
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting to give each app's urls.py an app_name when using namespaced reverse() lookups.
  2. Including an app's urls.py without a trailing prefix slash, producing unexpected concatenated paths.
  3. Duplicating the same route prefix in both the root urls.py and the app's urls.py.
Chapter Summary
  • include() lets the root URLconf delegate an entire URL prefix to an app's own urls.py.
  • Each app keeps its routes self-contained, which keeps the project URLconf short and organized.
  • app_name plus a namespace in include() enables namespaced {% url %} lookups like 'blog:post_detail'.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.