Django Custom Path Converters

Django Custom Path Converters

In django version 2.0 introduced new way to write url patterns using "path". In django 2.0 regular expression type "url" is removed and added 2 things to work with urls. 1. using "path" and 2. using "re_path". For writing the clean urls django provided the path converters. It helps us to write clean and neat code and improves code readability.

default path converters provided by dango

The syntax of path converter is "". path converter type is one of the defaults str, int, slug, uuid or a custom path converter if we have one. Let's see how we can use default path converters in django.

  • str
path('user/<str:username>/detail/', views.user_detail, name='user_detail')

In avobe code we have used "str" as a path converter and kwarg name is "username". consider the example url "user/anjaneyulu/detail/". when we access it the url dispatcher will check the string regex whether the url is pattern is matched or not after matching it will return the control to the view (views.user_detail). If url path not matched with the string pattern then it will lookfor other url paths and tries to match with other path patterns if not found it will raise 404 error.

  • int
path('author/<int:pk>/detail/', views.author_detail, name='author_detail')

In the above code we have used "int" as a path converter and "pk" as a kwarg name. The path converter already have the "int" regex. So, when we access url path that matches the pattern then the control will we passed to the view. If not it will tries to match for other paths and if not found it will raise a 404 error.

  • slug
path('blog/<slug:post_slug>/', views.blogpost_detail, name='blogpost_detail')

In the above code we have used "slug" as a path converter and "post_slug" as a kwarg name that will be passed view. The path converter is defined with the slug regex already. So, it will check the url with the slug regex and returns control to the view. Otherwise it will look for other url paths for matching if none matches it will raise 404 error, saying that url not found.

  • uuid
path('email/<uuid:user_uuid>/confirm/', name='user_email_conform')

In above code we have used "uuid" as a path converter and "user_uuid" as a kwarg name. The path converter already defined with uuid regex pattern. So, it will matches regex with given url path and if matches it will pass control to the view to return the response.

Writing custom path converters in django

A clean url is very important for any web application. Django is providing the best solution to this problem. We can write nice and clean urls using the path converters. Django already provides the default path converters but, in some cases we may need more. For example, If we want to show user details with username and we have some conditions for username like username must start with a letter, then either a-z (lowercase letters), A-Z (uppercase letters), 0-9 (numbers), underscores, periods and hyphens are allowed, and it must be between 8 and 20.

converters.py

class UsernamePathConverter:
    regex = '^[a-zA-Z0-9_.-]+$'

    def to_python(self, value):
        # convert value to its corresponding python datatype
        return value

    def to_url(self, value):
        # convert the value to str data 
        return value

urls.py

from django.urls import register_converter, path
from .views import views
register_converter(UsernamePathConverter, 'username')

urlpatterns = [
    # ....
    path('articles/<username:uname>/', views.user_detail, name="user_detail")
    # ....
]

In above code we have created path converter for username and registered it using "register_converter" function with name "username" and we used the path converter in the url path.

Points to be Noted: to_python method should raise ValueError if it can’t convert the given value.

Reference: https://docs.djangoproject.com/en/2.0/topics/http/urls/#registering-custom-path-converters