How to create a Unique Slug in Django Tutorial

In this tutorial, you will learn how to create unique Slug in Django. Some of the time you need Slug in your URL instead of Unique ID. This tutorial will teach how to make unique slug in your model. We can use slug field to identify objects in url.

Django Unique Slug Generation

Let’s say you have Employee Model in models.py

# models.py
from django.db import models

class EmpUser(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    mobile = models.CharField(max_length=12)
    email = models.EmailField(max_length = 254, unique=True) 

Now add a SlugField in your Model –

# models.py
from django.db import models

class EmpUser(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    mobile = models.CharField(max_length=12)
    email = models.EmailField(max_length = 254, unique=True) 
    slug = models.SlugField(max_length = 250, null = True, blank = True) 

Now migrate the model in Django.

Create Unique Function for Slug in Django

For creating unique slug in Django, we will be using Slugify and Django Signals.

But first we will create a function for Creating a Slug using first_name and if that first_name is present in slug field, we will attach unique string to slug.

import string 
from django.utils.text import slugify 
import random 
  
def random_string_generator(size = 10, chars = string.ascii_lowercase + string.digits): 
    return ''.join(random.choice(chars) for _ in range(size)) 
  
def unique_slug_generator(instance, new_slug = None): 
    if new_slug is not None: 
        slug = new_slug 
    else: 
        slug = slugify(instance.first_name) 
    Klass = instance.__class__ 
    qs_exists = Klass.objects.filter(slug = slug).exists() 
    if qs_exists: 
        new_slug = "{slug}-{randstr}".format( 
            slug = slug, randstr = random_string_generator(size = 4)) 
              
        return unique_slug_generator(instance, new_slug = new_slug) 
    return slug 

Note – In above code first_name is bolded, if you want to create slug with different fields, then just change it.

Now will create a function and pass that function to pre_save django signal in models.py

from django.db.models.signals import pre_save

def pre_save_receiver(sender, instance, *args, **kwargs): 
   if not instance.slug: 
       instance.slug = unique_slug_generator(instance) 

pre_save.connect(pre_save_receiver, sender = EmpUser) 

Thats it. This is how you can create unique slug in Django.

Here, I am sharing full code of my models.py file

from django.db import models
from django.db.models.signals import pre_save
from django.template.defaultfilters import slugify

from .utils import unique_slug_generator

import string 
from django.utils.text import slugify 
import random 
  

# Create your models here.
class EmpUser(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    mobile = models.CharField(max_length=12)
    email = models.EmailField(max_length = 254, unique=True) 
    slug = models.SlugField(max_length = 250, null = True, blank = True) 


def random_string_generator(size = 10, chars = string.ascii_lowercase + string.digits): 
    return ''.join(random.choice(chars) for _ in range(size)) 
  
def unique_slug_generator(instance, new_slug = None): 
    if new_slug is not None: 
        slug = new_slug 
    else: 
        slug = slugify(instance.first_name) 
    Klass = instance.__class__ 
    qs_exists = Klass.objects.filter(slug = slug).exists() 
      
    if qs_exists: 
        new_slug = "{slug}-{randstr}".format( 
            slug = slug, randstr = random_string_generator(size = 4)) 
              
        return unique_slug_generator(instance, new_slug = new_slug) 
    return slug 

def pre_save_receiver(sender, instance, *args, **kwargs): 
   if not instance.slug: 
       instance.slug = unique_slug_generator(instance) 

pre_save.connect(pre_save_receiver, sender = EmpUser) 

This is how we can call slug in urls.py

path('user/<slug:slug>/', EmpUserView.as_view(), name='user'),

Leave a Reply

Your email address will not be published. Required fields are marked *