Slugs, why would you ever need to store one in the database?

816 views
Skip to first unread message

nbv4

unread,
Jul 23, 2009, 10:30:15 AM7/23/09
to Django users
I'm looking into adding prettier URLs into my site with the help of
slugs. I've never done something like this before, so I'm doing a lot
of reading and am having trouble "getting" slugs. When creating URLs,
couldn't you just do do something like "example.com/45/slug-goes-
here"? Then have the view only use the 45 (the ID) to look up the blog
entry (or whatever). Then it checks to see if the slug matches, if it
does then carry on, if not, issue a redirect with the correct slug. It
seems like to me this is the easiest way to go about this, but in my
google searches, this is Not The Right Way (TM). It seems that the way
you're supposed to do it involves a seperate slug field that gets
stored in the database. What is the point of this? I'm about to
implement this the way I described above. Is there anything I'm
missing?

Also, is there some kind of "slugify" function build into django? I
know theres the slugify template tag, but what about something not in
that I can use in my models and views?

Shawn Milochik

unread,
Jul 23, 2009, 10:42:41 AM7/23/09
to django...@googlegroups.com
My understanding of the slug field is that prettier URLs are the main
point.

"Slug" is a newspaper-industry term, and since Django has its roots
there, it's now a Django term.

Django does' in fact, contain a slugify function:
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#slugify
You can import and use this in a view, not just in a template: from
django.template.defaultfilters import slugify

Note that it does not enforce uniqueness; you'd have to do that
yourself. We just append a number to the slug.
So, for example, if you already had john_smith as a slug, you'd end up
with john_smith2.

We use unique slugs, and store them in the database. The main reason
(I think) for storing it in the
database is the fact that you can easily retrieve a model instance
using (slug = value) in the objects.get().

Having the ID and the slug both passed in the URL is redundant. We use
one or the other. Your use case may
dictate a different approach, but it doesn't make sense to me to have
two values in the URL, both of which should
be referring to the exact same record.

Shawn

Michael

unread,
Jul 23, 2009, 10:44:50 AM7/23/09
to django...@googlegroups.com
On Thu, Jul 23, 2009 at 10:30 AM, nbv4 <cp36...@ohio.edu> wrote:

I'm looking into adding prettier URLs into my site with the help of
slugs. I've never done something like this before, so I'm doing a lot
of reading and am having trouble "getting" slugs. When creating URLs,
couldn't you just do do something like "example.com/45/slug-goes-
here"? Then have the view only use the 45 (the ID) to look up the blog
entry (or whatever). Then it checks to see if the slug matches, if it
does then carry on, if not, issue a redirect with the correct slug. It
seems like to me this is the easiest way to go about this, but in my
google searches, this is Not The Right Way (TM). It seems that the way
you're supposed to do it involves a seperate slug field that gets
stored in the database. What is the point of this? I'm about to
implement this the way I described above. Is there anything I'm
missing?

In general, some of us don't really care to expose the 45 part of that url. It is often a lot simpler to have a slug stored in the db and have it be the field that people use to look up entries. While I wouldn't say your way is wrong, the slug and the ID are redundant; they are both referring to the same thing. It helps SEO and humans to have short, concise and readable uris, so when you look at my blog post /python-rocks-my-socks/ you know what you are getting yourself into. Why put the extra ID there? You could also compute the uri on the fly if you don't want to store the slug in the DB, but that would require a lot of processing and essentially the same database lookup (WHERE `slug` EXACT 'python-rocks-my-socks') or something worse (WHERE `slug` IREGEX 'crazy regex processing'). It is easier to just store the slug IMO. 

Also, is there some kind of "slugify" function build into django? I
know theres the slugify template tag, but what about something not in
that I can use in my models and views?

Filters are nothing more than functions in Django, so:
In [1]: from django.template.defaultfilters import slugify

In [2]: slugify('Python rocks my socks')
Out[2]: u'python-rocks-my-socks'


 

Masklinn

unread,
Jul 23, 2009, 11:04:22 AM7/23/09
to django...@googlegroups.com
On 23 Jul 2009, at 16:30 , nbv4 wrote:
> I'm looking into adding prettier URLs into my site with the help of
> slugs. I've never done something like this before, so I'm doing a lot
> of reading and am having trouble "getting" slugs. When creating URLs,
> couldn't you just do do something like "example.com/45/slug-goes-
> here"? Then have the view only use the 45 (the ID) to look up the blog
> entry (or whatever).

Yes you could.

> It seems that the way
> you're supposed to do it involves a seperate slug field that gets
> stored in the database. What is the point of this? I'm about to
> implement this the way I described above. Is there anything I'm
> missing?

Well I usually set the slug field as the pk (which removes the `id`
field Django automatically adds to the table). That way I get
`example.com/slug-goes-here` and the view only uses the slug to look
up the item, not an artificial ID (naturally one can also consider the
slug to be artificial: since it's a transformation on the name/title
of the item/entry, one could use the name/title as a PK, though I
don't think even Django 1.1's extensions to the ORM handle that kind
of cases gracefully).

Alex Robbins

unread,
Jul 24, 2009, 8:24:56 AM7/24/09
to Django users
You might want to look into the SlugField [1]. It makes sure you only
have url friendly stuff. You can also autopopulate it from another
field in the admin[2]. That way you just type the title and it makes a
slug for you.

One reason to hide pks is that they allow people to learn more about
your site than you might want. They can guess the next user, see what
order things were created in, or even statistics and figure out things
like how many users sign up a month.[3]

[1]http://docs.djangoproject.com/en/dev/ref/models/fields/#slugfield
[2]http://docs.djangoproject.com/en/dev/ref/contrib/admin/
#django.contrib.admin.ModelAdmin.prepopulated_fields
[3]http://www.guardian.co.uk/world/2006/jul/20/
secondworldwar.tvandradio

Andy Mikhailenko

unread,
Jul 24, 2009, 12:47:24 PM7/24/09
to Django users
Just one more addition to the replies above: there's a number of
snippets[1], recipes and packages[2] which introduce purely
autogenerated safe (unique and sometimes also non-ascii-friendly)
slugs without using admin.

Autopopulated slugs, when used in URLs without exposing internal
autoincremented IDs, can be a problem if you change them (to match an
updated title) after the URL is bookmarked or linked somewhere else.
However, PKs can change too (e.g. splitting a topic in a forum or
merging it into another one, etc.), and slugs can help with hiding
away the implementation details so that you can keep the URLs
permanent without imposing unnecessary restrictions on models and
views.

[1] http://djangosnippets.org/tags/slug/
[2] http://pypi.python.org/pypi/django-autoslug
Reply all
Reply to author
Forward
0 new messages