Here you will learn what are the different ways to design URLs in Django using path and re_path.

Structure of path

Import path and re_path:

# From where to import

from django.urls import path, re_path

Let's understand how url's are designed from the example below.

urlpatterns = [
    path('articles/2003/', views.special_case_2003), #1
    path('articles/<int:year>/', views.year_archive),#2
    path('articles/<int:year>/<int:month>/', views.month_archive), #3
    path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),#4
]

#1: It is a simple URL pattern to match the exact string 'articles/2003/'.

#2: In this, a parameter year of type int is passed to the view, which can be accessed like

def myview(request,year=2000):
    print(year)

#3: In this case, the year and month of type int are passed to the view.

#4: year, month of type int and slug of type slug is passed to the view.

Note: int and slug are called path converters.

Default Path converters

str: Matches any non-empty string, excluding the path separator, '/'. This is the default if a converter isn’t included in the expression.

int: Matches zero or any positive integer. Returns an int.

slug: Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. For example, building-your-1st-django-site.

uuid: Matches a formatted UUID. To prevent multiple URLs from mapping to the same page, dashes must be included and letters must be lowercase. For example, 075194d3-6885-417e-a8a8-6c931e272f00. Returns a UUID instance.

path: Matches any non-empty string, including the path separator, '/'. This allows you to match against a complete URL path rather than just a segment of a URL path as with str.

Creating a custom path converter

For more complex matching requirements, you can define your own path converters.

A converter is a class that includes the following:

  • A¬†regex¬†class attribute, as a string.
  • A¬†to_python(self,¬†value)¬†method, which handles converting the matched string into the type that should be passed to the view function. It should raise¬†ValueError¬†if it can‚Äôt convert the given value. A¬†ValueError¬†is interpreted as no match and as a consequence, a 404 response is sent to the user.
  • A¬†to_url(self,¬†value)¬†method, which handles converting the Python type into a string to be used in the URL.

Create a file converters.py inside your app and paste the following:

class FourDigitYearConverter:
    regex = '[0-9]{4}'

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return '%04d' % value

Register custom converter classes in your URLconf using register_converter():

from django.urls import path, register_converter

from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
    path('articles/2003/', views.special_case_2003),
    path('articles/<yyyy:year>/', views.year_archive),
    ...
]

Using regular expressions

If the paths and converters syntax isn’t sufficient for defining your URL patterns, you can also use regular expressions. To do so, use re_path() instead of path().

In Python regular expressions, the syntax for named regular expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match. Some of the common useful URL patterns using re_path are

# Primary Key AutoField
re_path(r'^questions/(?P<pk>\d+)/$', views.question_details, name='question_details'),

# Slug Fields
re_path(r'^posts/(?P<slug>[-\w]+)/$', views.post, name='post'),

# Slug with Primary Key
re_path(r'^blog/(?P<slug>[-\w]+)-(?P<pk>\d+)/$', views.blog_post, name='blog_post'),

# Usernames
re_path(r'^profile/(?P<username>[\[email protected]+-]+)/$', views.user_profile),

# Dates
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive)

# Year / Month
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),

# Year / Month / Day
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail)

That's all.

Join this python and django newsletter to learn more about the similar topics. If you are a beginner in django, try this tutorial "how to structure a django project for beginners".