python - slugfield - slug url django
¿Cómo creo una babosa en Django? (9)
Estoy tratando de crear un SlugField en Django.
He creado este modelo simple:
from django.db import models
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
Entonces hago esto:
>>> from mysite.books.models import Test
>>> t=Test(q="aa a a a", s="b b b b")
>>> t.s
''b b b b''
>>> t.save()
>>> t.s
''b b b b''
>>>
Esperaba bbbb
En la mayoría de los casos, la bala no debería cambiar, por lo que realmente solo desea calcularla en el primer guardado:
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField(editable=False) # hide from admin
def save(self):
if not self.id:
self.s = slugify(self.q)
super(Test, self).save()
Estoy usando Django 1.7
Crea un SlugField en tu modelo como este:
slug = models.SlugField()
Entonces en admin.py
define admin.py
;
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
Hay un caso de esquina con algunos caracteres utf-8.
Ejemplo:
>>> from django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u''test-aescon'' # there is no "l"
Esto se puede resolver con Unidecode
>>> from unidecode import unidecode
>>> from django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u''test-aescoln''
Puede consultar la documentación del SlugField
para conocer más sobre él de manera más descriptiva.
Si está utilizando la interfaz de administración para agregar nuevos elementos de su modelo, puede configurar un ModelAdmin
en su admin.py
y utilizar los admin.py
para automatizar el ingreso de una bala:
class ClientAdmin(admin.ModelAdmin):
prepopulated_fields = {''slug'': (''name'',)}
admin.site.register(Client, ClientAdmin)
Aquí, cuando el usuario ingresa un valor en el formulario de administración para el campo de name
, la slug
se rellenará automáticamente con el name
slugified correcto.
Si no desea configurar el campo slug como No se puede editar, creo que querrá establecer las propiedades Null y Blank en False. De lo contrario, obtendrá un error al intentar guardar en Admin.
Entonces, una modificación al ejemplo anterior sería:
class test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField(null=True, blank=True) # Allow blank submission in admin.
def save(self):
if not self.id:
self.s = slugify(self.q)
super(test, self).save()
Tendrá que usar la función slugify.
>>> from django.template.defaultfilters import slugify
>>> slugify("b b b b")
u''b-b-b-b''
>>>
Puedes llamar a slugify
automáticamente anulando el método de save
:
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
def save(self, *args, **kwargs):
self.s = slugify(self.q)
super(Test, self).save(*args, **kwargs)
Tenga en cuenta que lo anterior hará que su URL cambie cuando se q
campo q
, lo que puede causar enlaces rotos . Puede ser preferible generar el slug solo una vez cuando crea un nuevo objeto:
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
def save(self, *args, **kwargs):
if not self.id:
# Newly created object, so set slug
self.s = slugify(self.q)
super(Test, self).save(*args, **kwargs)
Una pequeña corrección a la respuesta de Thepeer: Para anular la función save()
en las clases modelo, es mejor agregarle argumentos:
from django.utils.text import slugify
def save(self, *args, **kwargs):
if not self.id:
self.s = slugify(self.q)
super(test, self).save(*args, **kwargs)
De lo contrario, test.objects.create(q="blah blah blah")
generará un error force_insert
(argumento inesperado).
Use prepopulated_fields en su clase de administrador:
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Article, ArticleAdmin)