In this post we are going to know how to generate unique slug in django automatically. So what is slug? Consider the URL of this post: https://fazle.me/auto-generating-unique-slug-in-django/ . Here the bold part of the URL is called slug.
First, consider a model ‘Article’ in which we will generate the unique slug.
1 2 3 4 5 6 7 8 9 10 | from django.db import models class Article(models.Model): title = models.CharField(max_length=120) slug = models.SlugField(max_length=140, unique=True) content = models.TextField() def __str__(self): return self.title |
In our model ‘Article’ we have three fields: title, slug and content. Django provides a built-in model field for slug, SlugField. We will generate the slug based on the title field.
How the slug will be generated: If the title of our first article is ‘New article’, the slug will be ‘new-article’. If the title of our second article is also ‘New article’, the slug will be ‘new-article-1’. And if the title of our third article is ‘New article’ again, the slug will be ‘new-article-2’. And so on.
So, to do that we have to write code like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | from django.db import models from django.utils.text import slugify class Article(models.Model): title = models.CharField(max_length=120) slug = models.SlugField(max_length=140, unique=True) content = models.TextField() def __str__(self): return self.title def _get_unique_slug(self): slug = slugify(self.title) unique_slug = slug num = 1 while Article.objects.filter(slug=unique_slug).exists(): unique_slug = '{}-{}'.format(slug, num) num += 1 return unique_slug def save(self, *args, **kwargs): if not self.slug: self.slug = self._get_unique_slug() super().save(*args, **kwargs) |
Look at the line 22, we override the save() method here. If the slug doesn’t already exist in the instance of Article, we generate it by calling _get_unique_slug() method. I am not explaining the code of _get_unique_slug() method in detail because it is kind of self explanatory. But what slugify() does? Well, if we give a string like ‘The new article title’ to slugify(), it returns ‘the-new-article-title’. Simple.
Update: 13/June/2018: It could be a better idea to use pre_save signal instead of overriding the save method what I have done in this post.
Thanks for reading this post. Have a nice day!
You should consider to read this post as well: Auto generating unique slug in Django: a generic approach.
Spin up your first SSD cloud server on DigitalOcean with $10 free credit!
Hi –thanks for this! Quick question–how do you handle this if you are entering information via the Admin–where it is requesting the slug field? Do you just fill it in with something similar to the title? When i try it –my admin won’t let me submit unless i fill in the field.
You can prepopulate the slug field based on the title field in admin by adding this line to your ModelAdmin:
prepopulated_fields = {'slug': ('title',)}
ahhh…ok makes sense–thanks man!
Hi, I am totally new to Django and am running into a bind with this line of code, do I need to add something else? I still get the error I need to fill out the slug field.
Also my editor tells me that super() needs an additional argument:
super() takes at least 1 argument (0 given).
Am I missing something from what you’ve written?
Hey @J, In django admin site, if you want to prepopulate the slug field based on the title field, you will need to put that line of code in your ModelAdmin. More info.
About
super()
: Probably you are using python 2.x. In that case, you need to writesuper(Article, self)
. In python 3.x you can write justsuper()
.Does this also handle generating new slugs for already existing entries?
Yes.
When do the _get_unique_slug and save methods get executed?
When you save an Article object.
Thanks for the article. Really easy to follow and works for me – just one quick question. I’m pretty new to python / Django. Where do you find info on the ‘{}’. syntax?
Thanks again
Hey, it is the new style of string formatting in python. You may want to look at this: https://pyformat.info/.
Thanks for clarifying the unique slugifying method.
What is the reason for defining the method “_get_unique_slug(self)” beginning with an underscore “_”?
This article may help you to understand.
Hello! Thank You for your post, it helped me a lot. But I am not sure about this thing:
super().save()
, I think that it should be something like this:super().save(*args, **kwargs)
, isn’t it?Yeah, you are right, that’s better.
Could you explain why using the pre_save signal is a better idea and how you’d integrate it into your model?
Will write a separate post if I get time.