Slugify Urls in Django

Slugify Urls in Django


In this tutorial, we will learn how to slugify urls in Django.
A Slug is a short label for something, containing only letters, underscores or hyphens.
Slugs are generally used in URL, For example in a typical blog entry URL:
https://www.kodnito.com/posts/slugify-urls-in-django
In the url, the slugify-urls-in-django is the slug.

Sample Project


$ mkdir django_slugify && cd django_slugify
$ pipenv install django
$ pipenv shell
$ django-admin startproject config .
$ python manage.py startapp posts

Open the models.py in posts applications and make it look like the following:


from django.db import models
from django.utils.text import slugify


class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

This will not work if two posts will have same title, and there are multiple ways of generating unique slugs. You could generate slugs combined with username, uuid or random string.

Here is an example with random string:


import string
import random

from django.db import models
from django.utils.text import slugify


def rand_slug():
    return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(6))


class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, unique=True)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(rand_slug() + "-" + self.title)
        super(Post, self).save(*args, **kwargs)

Now, with all Django applications, we have to update settings.py and add our new application.


INSTALLED_APPS = [
    ...
    'posts.apps.PostsConfig',
]
Run the following commands to create the new post table.


$ python manage.py makemigrations
$ python manage.py migrate

We will use the interactive Python shell to create a new post. To start the Python shell, use the following command:


$ python manage.py shell

>>> from posts.models import Post
>>> post = Post.objects.create(title='Slugify Urls in Django')
>>> post.slug
'slugify-urls-in-django'

That's it, slugs will be auto-generated and now we can use slug, instead of using PK's in the urls like this:
I

urlpatterns = [
    path('posts/<slug:slug>/', PostDetailView.as_view(), name='post_detail'),
]


Share this: