¿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