O que é SlugField no Django?
É uma forma de gerar um URL válido, geralmente utilizando dados já obtidos. Por exemplo, usando o título de um artigo para gerar um URL.

Vamos supor que nosso blog tenha uma postagem com o título 'O livro Django de Geeksforgeeks' com a chave primária id = 2. Podemos nos referir a esta postagem com www.geeksforgeeks.org/posts/2. Ou podemos fazer referência ao título como www.geeksforgeeks.org/posts/The Django book by Geeksforgeeks.
Mas o problema é que os espaços não são válidos em URLs, eles precisam ser substituídos por % 20, o que é feio, tornando-o o seguinte, www.geeksforgeeks.org/posts/The%20Django%20book%20by%20geeksforgeeksmas não está resolvendo URL significativo. Outra opção pode ser www.geeksforgeeks.org/posts/the-django-book-by-geeksforgeeks.
Então, a lesma é agora the-django-book-by-geeksforgeeks. Todas as letras são reduzidas e os espaços são substituídos por hifens -.

Suponha que nossos modelos de postagem no blog sejam semelhantes a este.

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 

Adicionando Slugify em nosso projeto:
Agora precisamos encontrar uma maneira de converter o título em slug automaticamente.

Nota: Adicione um novo arquivo util.pyno mesmo diretório onde o settings.py arquivo foi salvo.



Queremos que este script seja acionado toda vez que uma nova instância do modelo Post for criada. Para isso, usaremos sinais.

import string 
from django.utils.text import slugify 
  
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.title) 
    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 

Sinais no Django:
Em muitos casos, quando há uma modificação na instância de um modelo, precisamos executar alguma ação. Django nos fornece uma maneira elegante de lidar com essas situações. Os sinais são utilitários que permitem associar eventos a ações. Podemos desenvolver uma função que será executada quando um sinal a chamar.

No models.pyarquivo do aplicativo de postagens onde o Post Model foi definido, adicione-o no mesmo arquivo:

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 = Post) 

A pre_save_receiver função deve ser colocada separadamente fora do modelo Post.

Nota: Em urls.pyeditar o caminho de detalhes com path('posts/', detail). Em views.pyeditar a função de detalhe com

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) 

A última etapa é adicionar o link no arquivo HTML <a href=”/posts/{{ a.slug }}” class=”btn btn-primary”> Visualização </a>. Agora estamos prontos para ir para 127.0.0.1:8000/posts/title-you-have-added e ele irá mostrar a página details.html.