Skip to content

reverse() in django

In Django, the reverse() function is a powerful utility provided by the django.urls module that helps generate URLs for Django views based on their names and optional parameters. It is primarily used to avoid hardcoding URLs in your Django applications, promoting better code organization, maintainability, and flexibility.

How it works

How reverse() Works

The reverse() function takes the following parameters:

  • viewname: This parameter is typically the name of a view function or a named URL pattern defined in your Django application's URL configuration (urls.py).

  • args: Optional parameter that holds a list or tuple of positional arguments that the view function expects. These arguments are used to construct the final URL.

  • kwargs: Optional parameter that holds a dictionary of keyword arguments that the view function expects. These arguments are also used to construct the final URL.


Names and namespaces

Always name your patterns. It helps in decoupling your code from the exact URL paths. For instance, in the previous URLConf, if you want to redirect to the About page, it might be tempting to use redirect("/about") . Instead, use redirect("about") , as it uses the name rather than the path.

>>> from django.urls import reverse
>>> reverse("hello_fn")
/hello-fn/
>>> reverse("year_view", kwargs={"year": "793"})
/year/793/

Defination

Name is like a nickname or label you give to a specific web address (URL) in your Django application. It's used so you can easily refer to that URL in your code without having to remember or repeat the actual URL string.

Example:

If your Django app has a page for "About Us" with the URL /about/, you can name it 'about'. So, instead of writing /about/ everywhere in your code, you just use 'about'.

from django.urls import path
from . import views

urlpatterns = [
    path('about/', views.about, name='about'),
    path('detail/<int:pk>/', views.detail, name='detail'),
    # Other URL patterns...
]

Namespace is a way to group and organize URLs from different parts of your Django project, especially useful when you have multiple apps with their own URLs. It helps prevent URLs from conflicting with each other.

Example:

Imagine you have two Django apps: blog and shop. Both might have a page named 'detail', but they mean different things (like a blog post detail versus a product detail). By using namespaces like 'blog:detail' and 'shop:detail', Django knows which one you're referring to.

from django.urls import include, path

urlpatterns = [
    path('myapp/', include('myapp.urls', namespace='myapp')),
    # Other URL patterns...
]

app_name is used inside a Django app's urls.py file to set the namespace for all the URLs defined in that file. It's like giving a name to the collection of URLs within that app, so Django can organize them correctly.

app_name in Django is a variable used within a Django application's urls.py file to define the application namespace for its URL patterns.

Example:

In your blog app's urls.py, if you set app_name = 'blog', then all URLs defined there will belong to the 'blog' namespace. This helps Django resolve URLs correctly when you use functions like reverse() to generate URLs dynamically.

from django.urls import path
from . import views

app_name = 'myapp'

urlpatterns = [
    path('', views.index, name='index'),
    path('about/', views.about, name='about'),
    path('detail/<int:pk>/', views.detail, name='detail'),
    # Other URL patterns...
]
Example
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
    path('', views.index, name='index'),  # URL: /blog/
    path('post/<int:pk>/', views.post_detail, name='post_detail'),  # URL: /blog/post/1/
    # Other URL patterns specific to the blog app...
]
from django.urls import path
from . import views

app_name = 'shop'

urlpatterns = [
    path('', views.index, name='index'),  # URL: /shop/
    path('product/<int:pk>/', views.product_detail, name='product_detail'),  # URL: /shop/product/1/
    # Other URL patterns specific to the shop app...
]
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls', namespace='blog')),  # Include blog app URLs with namespace 'blog'
    path('shop/', include('shop.urls', namespace='shop')),  # Include shop app URLs with namespace 'shop'
    # Other project-specific URL patterns...
]

Pattern order

Order your patterns to take advantage of how Django processes them, that is, top-down. A good rule of thumb is to keep all the special cases at the top. Broader or more general patterns can be mentioned further down. The broadest, a catch-all-if present, can go at the very end.

For example, the path to your Blog posts might be any valid set of characters, but you might want to handle the About page separately. The right sequence of patterns should be as follows:

blog_patterns = [
    path('about/', views.AboutView.as_view(), name= 'about'),
    path('<slug:slug>/', views.ArticleView.as_view(), name='article'),
]

if we reverse the order, then the special case, the AboutView, will never get called.

URL pattern styles

Designing URLs of a site can easily be consistently overlooked. Well-designed URLs can not only logically organize your site, but can also make it easy for users to guess paths. Poorly designed ones can even be a security risk: for example, using a database ID (which occurs in a monotonic increasing sequence of integers) in a URL pattern can increase the risk of information theft or site ripping. Let's examine some common styles followed in designing URLs.


Reference