Agregue el campo slug dentro del modelo Django

¿Qué es SlugField en Django? 

Es una forma de generar una URL válida, generalmente utilizando datos ya obtenidos. Por ejemplo, usar el título de un artículo para generar una URL. Supongamos que nuestro blog tiene una publicación con el título ‘El libro de Django de Geeksforgeeks’ con id de clave principal = 2. Podríamos referirnos a esta publicación con 

www.geeksforgeeks.org/posts/2. 

O bien, podemos hacer referencia al título como

 www.geeksforgeeks.org/posts/The Django book by Geeksforgeeks. 

Pero el problema es que los espacios no son válidos en las URL, deben reemplazarse por % 20 , que es feo, por lo que es el siguiente 

www.geeksforgeeks.org/posts/The%20Django%20book%20by%20geeksforgeeks 

Pero no está resolviendo una URL significativa. Otra opción puede ser

 www.geeksforgeeks.org/posts/the-django-book-by-geeksforgeeks

Entonces, la babosa ahora es the-django-book-by-geeksforgeeks . Todas las letras están en minúsculas y los espacios se reemplazan por guiones -. 
 

Supongamos que nuestros modelos de publicación de blog se parecen a este. 

Python3

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

Agregando Slugify a nuestro proyecto: 
 

Ahora necesitamos encontrar una forma de convertir el título en un slug automáticamente. Queremos que este script se active cada vez que se crea una nueva instancia del modelo Post . Para ello, utilizaremos señales. 
 

Nota: Agregue un nuevo archivo util.py en el mismo directorio donde se guarda el archivo settings.py. 

Python3

import string, random
from django.db.models.signals import pre_save
from django.dispatch import receiver
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__
    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

Señales en Django: 

En muchos casos cuando hay una modificación en la instancia de un modelo necesitamos ejecutar alguna acción. Django nos proporciona una forma elegante de manejar estas situaciones. Las señales son utilidades que permiten asociar eventos con acciones. Podemos desarrollar una función que se ejecutará cuando una señal la llame. 
En el archivo models.py de la aplicación de publicaciones donde se definió Post Model, agregue esto en el mismo archivo: 
 

Python3

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

La función pre_save_receiver debe colocarse por separado fuera del modelo Post.
 

Nota: En urls.py, edite la ruta detallada con ruta (‘publicaciones/’, detalle). En views.py edite la función de detalle con 
 

Python3

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)

El último paso es agregar el enlace en el archivo HTML <a href=”/posts/{{ a.slug }}” class=”btn btn-primary”>Ver</a>. Ahora estamos listos para ir a 127.0.0.1:8000/posts/title-you-have-added y le mostrará la página details.html .
 

Publicación traducida automáticamente

Artículo escrito por ishwarjangid y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *