J'essaie de créer un SlugField
dans Django.
J'ai créé ce modèle simple:
from Django.db import models
class Test(models.Model):
q = models.CharField(max_length=30)
s = models.SlugField()
Je fais alors ceci:
>>> 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'
Je m'attendais à b-b-b-b
.
Vous devrez utiliser la fonction slugify.
>>> from Django.template.defaultfilters import slugify
>>> slugify("b b b b")
u'b-b-b-b'
>>>
Vous pouvez appeler slugify
automatiquement en redéfinissant la méthode 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)
Sachez que ce qui précède entraînera une modification de votre URL lorsque le champ q
sera modifié, ce qui peut provoquer des liens rompus . Il peut être préférable de générer le slug une seule fois lorsque vous créez un nouvel objet:
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)
Il y a un coin avec quelques caractères utf-8
Exemple:
>>> from Django.template.defaultfilters import slugify
>>> slugify(u"test ąęśćółń")
u'test-aescon' # there is no "l"
Ceci peut être résolu avec nidecode
>>> from unidecode import unidecode
>>> from Django.template.defaultfilters import slugify
>>> slugify(unidecode(u"test ąęśćółń"))
u'test-aescoln'
Une petite correction à la réponse de Thepeer: pour remplacer save()
dans les classes de modèle, il vaut mieux y ajouter des arguments:
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)
Sinon, test.objects.create(q="blah blah blah")
entraînera une erreur force_insert
(Argument inattendu).
Si vous utilisez l'interface d'administration pour ajouter de nouveaux éléments à votre modèle, vous pouvez configurer un ModelAdmin
dans votre admin.py
et utiliser prepopulated_fields
pour automatiser l’entrée d’un slug:
class ClientAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name',)}
admin.site.register(Client, ClientAdmin)
Ici, lorsque l'utilisateur saisit une valeur dans le formulaire d'administration pour le champ name
, le slug
sera automatiquement renseigné avec le correct slugified name
.
Dans la plupart des cas, le slug ne devrait pas changer, vous ne voulez donc le calculer que lors de la première sauvegarde:
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()
Utilisation prepopulated_fields
dans votre classe d'admin:
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Article, ArticleAdmin)
Si vous ne souhaitez pas définir le slugfield sur Ne pas être éditable, je pense que vous voudrez définir les propriétés Null et Blank sur False. Sinon, vous obtiendrez une erreur en essayant de sauvegarder dans Admin.
Donc, une modification à l'exemple ci-dessus serait ::
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()
J'utilise Django 1.7
Créez un SlugField dans votre modèle comme ceci:
slug = models.SlugField()
Puis dans admin.py
définir prepopulated_fields
;
class ArticleAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}