web-dev-qa-db-fra.com

Pourquoi SlugField () dans Django?

Django a models.SlugField() ce qui nous aide à créer des URL à l'aspect cool. Ma question est pourquoi le spécifier en tant que champ

suppose que j'ai ceci modèle

 class Blog(models.Model):
    title = models.CharField()

et si je veux ajouter une limace, je pourrais simplement utiliser

 class Blog(models.Model):
    title = models.CharField()

    def title_slug(self):
       return slugify(self.title)

in rls je pourrais simplement utiliser

(r'^blog/(?P<id>\d+)/(?P<slug>[-\w]+)/$', 'app.views.blog_view'),

et dans vues

def blog_view(request, id ,slug):
    get_object_or_404(Blog, pk=id)
    ...

les URL ressembleront

example.com/blog/23/why-iam-here/

Il y a trois choses qui me font adopter cette méthode

  1. Le champ Slug n'est pas livré avec unicité implicite.
  2. get_object_or_404(Blog, pk=id) doit être plus rapide que get_object_or_404(Blog, slug=slug).
  3. L'ajout d'un champ de slug aux modèles existants implique la migration des données.

alors pourquoi SlugField ()? , à part le coût de génération dynamique de slug, quels sont les inconvénients de la méthode ci-dessus?

41
Ryu_hayabusa

Pourquoi SlugField () dans Django? Car:

  1. il est convivial pour les humains (par exemple./blog/au lieu de/1 /).
  2. c'est un bon référencement pour créer une cohérence dans le titre, le titre et l'URL.

Le gros inconvénient de votre slug généré dynamiquement, accepter des slugs dans urls.py et ne pas utiliser le slug pour obtenir le bon objet? C'est une mauvaise conception.

Si vous fournissez et acceptez des slugs, mais ne les comparez pas, vous disposez de plusieurs URL renvoyant le même contenu. Donc /1/slug-utile/ et /1/this-is-a-bs-slug/ renverra tous les deux la même page.

C'est mauvais car cela ne facilite pas la vie des humains. Vos visiteurs doivent fournir un identifiant et quelque chose qui est redondant. Les pages dupliquées sont des cauchemars pour les moteurs de recherche. Quelle page est la bonne? Les pages dupliquées se retrouveront avec un faible rang. Voir https://support.google.com/webmasters/answer/40349?hl=en (dernier p)

Vous pouvez affirmer que vous implémentez vos propres liens magnifiquement générés de manière cohérente, mais les gens et les robots supposent constamment les URL (consultez vos fichiers journaux). Lorsque vous acceptez toutes les limaces, les humains et les robots devinent toujours bien.

L'enregistrement d'une limace dans la base de données permet également d'économiser de la puissance de traitement. Vous générez le slug une fois et le réutilisez. Quoi de plus (in) efficace pour rechercher la limace ou la générer à chaque fois?

Les champs de slug dans l'administrateur sont utiles pour donner aux éditeurs la possibilité de modifier le slug. Peut-être pour fournir des informations supplémentaires qui ne sont pas dans le titre mais qui méritent tout de même d'être mentionnées.

Bonus: pour mettre à jour les données migrées:

from Django.template.defaultfilters import slugify

for obj in Blog.objects.filter(slug=""):
    obj.slug = slugify(obj.title)
    obj.save()
33
allcaps

Le champ Slug n'est pas livré avec unicité implicite.

Il n'y a pas d'unicité implicite avec un CharField. Vous devez spécifier unique=True si vous voulez vous assurer que chaque ligne est unique au niveau de la base de données. Vous devez le faire avec à la fois un CharField et un SlugField donc aucun avantage non plus

get_object_or_404 (Blog, pk = id) doit être plus rapide que get_object_or_404 (Blog, slug = slug).

Il peut y avoir une très légère différence en raison d'un index sur votre clé primaire, mais c'est probablement négligeable. Cela n'a rien à voir avec l'utilisation d'un CharField vs SlugField - vous venez de créer une URL différente qui prend un id et vous l'utilisez pour faire la recherche.

L'ajout d'un champ de slug aux modèles existants implique la migration des données.

L'ajout d'un CharField à un modèle existant a également nécessité une migration des données, il n'y a donc aucun avantage ici.


SlugFields sont simplement CharField avec un peu de validation supplémentaire. Regardez le code . Vous violez la règle d'or de Django de DRY - ne vous répétez pas.

De plus, si vous utilisez simplement un CharField vous n'obtenez aucune validation au niveau du formulaire, vous pouvez donc très facilement créer un "slug" qui n'est pas conforme à la validation des slugs, c'est-à-dire qu'il pourrait avoir des espaces ou des caractères non autorisés dans une URL.

Toujours avec cette approche, si vous changez de titre, votre URL a changé et maintenant tous vos anciens liens sont morts. Avoir un champ de slug empêche cela.

Vous vous faites plus de mal ici - utilisez simplement le SlugField

11
Timmy O'Mahony