Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 11, 2022 02:53 pm GMT

Add the slug field inside Django Model

## What is Slug Field in Django?

It is a way of generating a valid URL, generally using data already obtained. For instance, using the title of an article to generate a URL. Lets assume our blog have a post with the title My First Post with primary key id= 2. We might refer to this post with

www.example.com/posts/2

Or, we can reference the title like

www.example.com/posts/my first post

But the problem is spaces are not valid in URLs, they need to be replaced by %20 which is ugly, making it the following

www.example.com/posts/my%20first%20post

But it is not solving meaningful URL. Another option can be

www.example.com/posts/my-first-post

So, the slug is now my-first-post. All letters are down cased and spaces are replaced by hyphens -. These URLs are extremely SEO Friendly.

Assume that our Blog Post models look similar to this.
Adding Slugify to our project:

STATUS_CHOICES = (('draft', 'Draft'),('published', 'Published'),)class Post(models.Model):title = models.CharField(max_length = 250)slug = models.SlugField(max_length = 250, null = True, blank = True)text = models.TextField()published_at = models.DateTimeField(auto_now_add = True)updated = models.DateTimeField(auto_now = True)status = models.CharField(max_length = 10, choices = STATUS_CHOICES,             default ='draft')class Meta: ordering = ('-published_at', )def __str__(self): return self.title

Now we need to find a way to convert the title into a slug automatically. We want this script to be triggered every time a new instance of Post model is created. For this purpose, we will use signals.

Note: Add new file util.py in the same directory where settings.py file is saved.

import string, randomfrom django.db.models.signals import pre_savefrom django.dispatch import receiverfrom django.utils.text import slugifydef 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.title) Klass = instance.__class__ max_length = Klass._meta.get_field('slug').max_length slug = slug[:max_length] qs_exists = Klass.objects.filter(slug = slug).exists() if qs_exists:  new_slug = "{slug}-{randstr}".format(   slug = slug[:max_length-5], randstr = random_string_generator(size = 4))  return unique_slug_generator(instance, new_slug = new_slug) return slug

Signals in Django:

In many cases when there is a modification in a models instance we need to execute some action. Django provides us with an elegant way to handle these situations. The signals are utilities that allow associating events with actions. We can develop a function that will run when a signal calls it.
In models.py file of posts app where Post Model was defined, add this in the same file:

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

The pre_save_receiver function should be placed separately outside the Post model.

Note: In urls.py edit detail path with path(posts/, detail). In views.py edit the detail function with

def detail(request, slug): q = Post.objects.filter(slug__iexact = slug)if q.exists(): q = q.first()else: return HttpResponse('<h1>Post Not Found</h1>')context = {'post': q}return render(request, 'posts/details.html', context)

The last step is to add the link in HTML file View. Now we are ready to go to 127.0.0.1:8000/posts/title-you-have-added and it will show you the page details.html.

Note: You Might have to import the modules into your models.py too.

Thats It!

Now your Blog will automatically convert title into slug.


Original Link: https://dev.to/anandhuprakash/add-the-slug-field-inside-django-model-5cd9

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To