Question

class Foo(models.Model):
    title = models.CharField(max_length=20)
    slug = models.SlugField()

Existe-t-il un moyen intégré pour que le champ slug soit automatiquement peuplé en fonction du titre? Peut-être dans l'administrateur et en dehors de l'administrateur.

Était-ce utile?

La solution

pour Admin dans Django 1.0 et supérieur, vous devez utiliser

prepopulated_fields = {'slug': ('title',), }

dans votre admin.py

Votre clé dans le dictionnaire prepopulated_fields est le champ que vous souhaitez renseigner et la valeur est un tuple de champs que vous souhaitez concaténer.

En dehors de l'administrateur, vous pouvez utiliser la fonction slugify dans vos vues. Dans les modèles, vous pouvez utiliser le filtre | slugify .

Il existe également ce paquet qui s’occupera automatiquement de cela: https: //pypi.python .org / pypi / django-autoslug

Autres conseils

En dehors de l'administrateur, consultez cet extrait de code Django . Placez-le dans votre .save () , et cela fonctionnera avec les objets créés par programme. Dans l’administrateur, comme d’autres l'ont dit, utilisez prepopulated_fields .

Pour les versions antérieures à 1.0:

slug = models.SlugField(prepopulate_from=('title',))

devrait fonctionner très bien

Pour la version 1.0, utilisez de camflan

Vous pouvez également utiliser le signal django pré_save pour remplir le slug en dehors du code administrateur django. Consultez la documentation relative à Django .

La validation de l'unicité des slugs Ajax sera également utile, voir Validation de l'unicité des slugs au fur et à mesure @ l'exubérance irrationnelle

autoslug a très bien fonctionné pour moi par le passé. Bien que je n’aie jamais essayé de l’utiliser avec l’application admin.

Je pensais ajouter une réponse complète et à jour avec les pièges mentionnés:

1. Remplir automatiquement les formulaires dans Django Admin

Si vous souhaitez uniquement ajouter et mettre à jour des données dans l’administrateur, vous pouvez simplement utiliser attribut prepopulated_fields

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

admin.site.register(Article, ArticleAdmin)

2. Générer automatiquement des formulaires personnalisés dans des modèles

Si vous avez créé votre propre interface rendue par le serveur avec des formulaires, vous pouvez renseigner automatiquement les champs à l'aide de | slugify filtre tamplate ou le utilitaire slugify lors de l’enregistrement du formulaire (is_valid).

3. Les slugfields à remplissage automatique au niveau du modèle avec django-autoslug

Les solutions ci-dessus ne rempliront automatiquement le slugfield (ou n’importe quel champ) lorsque les données seront manipulées via ces interfaces (l’admin ou un formulaire personnalisé). Si vous avez une API, des commandes de gestion ou tout autre outil manipulant également les données à transférer au niveau du modèle.

django-autoslug fournit les champs AutoSlugField qui étend SlugField et permet de définir quel domaine il devrait slugify proprement:

class Article(Model):
    title = CharField(max_length=200)
    slug = AutoSlugField(populate_from='title')

Le champ utilise les signaux pre_save et post_save pour obtenir ses fonctionnalités. Veuillez donc consulter le texte relatif à la situation au bas de cette réponse.

4. Remplissage automatique des slugfields au niveau du modèle en remplaçant save ()

La dernière option consiste à l'implémenter vous-même, ce qui implique de remplacer la méthode save () par défaut:

    class Article(Model):
        title = CharField(max_length=200)
        slug = SlugField()

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(Job, self).save(*args, **kwargs)

REMARQUE: les mises à jour groupées contournent votre code (y compris les signaux)

Ceci est une mauvaise compréhension commune des débutants à Django. Premièrement, vous devez savoir que les signaux pre_save et post_save sont directement liés à la méthode save (). Deuxièmement, les différentes façons d'effectuer des mises à jour en bloc dans Django contournent toutes la méthode save () pour obtenir des performances élevées, en opérant directement sur la couche SQL. Cela signifie que pour l'exemple de modèle utilisé dans les solutions 3 ou 4 ci-dessus:

  • Article.objects.all (). update (title = 'Nouveau message') va PAS mettre à jour le slug de tout article
  • Utilisation de bulk_create ou bulk_update sur le modèle d'article sera PAS met à jour le slug de n’importe quel article.
  • La méthode save () n'étant pas appelée, aucun signal pré-enregistrement ou post-enregistrement ne sera émis .

Pour effectuer des mises à jour en bloc tout en utilisant des contraintes au niveau du code, la seule solution consiste à itérer les objets un par un et à appeler sa méthode save (), qui a considérablement moins de performances que les opérations en bloc au niveau SQL. Vous pouvez bien sûr utiliser des déclencheurs dans votre base de données, bien que ce soit un sujet totalement différent.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top