Question

Django has models.SlugField() which helps us to create some cool looking urls. My question is why specifying it as a field

suppose I have this model

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

and if I want to add slug, I could just use

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

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

in urls I could just use

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

and in views

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

urls will look like

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

There are three things that makes me adopt this method

  1. Slug field does not comes with implicit uniqueness.
  2. get_object_or_404(Blog, pk=id) must be faster than get_object_or_404(Blog, slug=slug).
  3. Adding a slug field to existing models involves data migration.

so why SlugField()? , apart from the cost of dynamically generating slug, what are the disadvantages of above method ?

Was it helpful?

Solution

Why SlugField() in Django? Because:

  1. it's human friendly (eg. /blog/ instead of /1/).
  2. it's good SEO to create consistency in title, heading and URL.

The big disadvantage of your dynamically generated slug, accepting slugs in urls.py and not using the slug to get the right object? It's bad design.

If you supply and accept slugs, but don't check against them, then you have multiple URLs returning the same content. So /1/useful-slug/ and /1/this-is-a-bs-slug/ will both return the same page.

This is bad because it does not make life easy for humans. Your visitors have to supply an id and something that is redundant. Duplicated pages are search engines nightmare. Which page is the right one? Duplicated pages will end up with a low rank. See https://support.google.com/webmasters/answer/40349?hl=en (last p)

You can argue that you implement your own beautifully generated links consistently, but people and bots guess URLs all the time (see your logfiles). When you accept all slugs then humans and bots always guess right.

Also saving a slug to the db saves processing power. You generate the slug one time and reuse it. What will be more (in)efficient looking up the slug or generating it each time?

Slug fields in the admin are useful to give editors the opportunity to edit the slug. Maybe to supply extra information that is not in the title but still worth mentioning.

Bonus: To update migrated data:

from django.template.defaultfilters import slugify

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

OTHER TIPS

Slug field does not comes with implicit uniqueness.

There is no implicit uniqueness with a CharField. You need to specify unique=True if you want to ensure that each row is unique at the DB level. You must do this with both a CharField and a SlugField so no advantage to either

get_object_or_404(Blog, pk=id) must be faster than get_object_or_404(Blog, slug=slug).

There might be a very slight difference due to an index on your primary key, but it's probably negligible. This has nothing to do with using a CharField vs SlugField though - you have just created a different URL that takes an id and are using that to do the lookup.

Adding a slug field to existing models involves data migration.

Adding a CharField to an existing model also required a data migration so there is no advantage here.


SlugFields are simply CharField with an extra bit of validation. Look at the code. You are breaking Django's golden rule of DRY - don't repeat yourself.

Furthermore, if you just use a CharField you don't get any validation at the form level, so you can very easily create a "slug" that doesn't conform to the slugs validation, i.e. it might have spaces or characters that are not allowed in an URL.

Also with this approach, if you change your title, your URL has changed and now all your old links are dead. Having a slug field prevents this.

You are making more trouble for yourself here - just use the SlugField

I am making a multi-tenant calendar app. If the calendar urls were something like: /calendar/id/ where the ids were successive integers, then hackers could guess the ids and find out more about my business than I want. By using a url /calendar/slug/ it is much harder to find all the calendars.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top