Sunday, September 22, 2013

Django - SlugField

If you are working with Apache and some CMS (e.g. Wordpress), you will find yourself at least do the url rewrite thing once to make the url friendly. Something like translate:

this:
http://mydomain.com/?q=abcd

to this:
http://mydomain.com/abcd/


In Django, you dont have to worry about it because when creating apps, Django lets you define the url pattern (regex) for a particular view. It is used in a pre-defined view. How about the user-defined view, like a blog post which will be posted by a non-programmer user using a WYSIWYG editor of your app? What will the url look like?

Django core developers (who develop the Django core) know that situation and create a Model Field name SlugField which will solve our problem:


James Bennett's definition from the book "Practical Django projects":

SlugField is a bit more interesting. It’s meant to store a slug: a short, meaningful piece of text, composed entirely of characters that are safe to use in a URL. You use SlugField when you generate the URL for a particular object. This means, for example, that instead of having a URL like /categories?category_id=47, you could have /categories/programming/. This is useful to your site’s visitors (because it makes the URL meaningful and easier to remember) and for search-engine indexing. URLs that contain a relevant word often rank higher in Google and other search engines than URLs that don’t. The term slug, as befits Django’s heritage, comes from the newspaper industry, where it is used in preprint production and sometimes in wire formats as a shorter identifier for a news story.


Django's documentation: 

SlugField

class SlugField([max_length=50**options])
Slug is a newspaper term. A slug is a short label for something, containing only letters, numbers, underscores or hyphens. They’re generally used in URLs.
Like a CharField, you can specify max_length (read the note about database portability and max_length in that section, too). If max_length is not specified, Django will use a default length of 50.
Implies setting Field.db_index to True.
It is often useful to automatically prepopulate a SlugField based on the value of some other value. You can do this automatically in the admin usingprepopulated_fields.

ModelAdmin.prepopulated_fields

Set prepopulated_fields to a dictionary mapping field names to the fields it should prepopulate from:
class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
When set, the given fields will use a bit of JavaScript to populate from the fields assigned. The main use for this functionality is to automatically generate the value for SlugField fields from one or more other fields. The generated value is produced by concatenating the values of the source fields, and then by transforming that result into a valid slug (e.g. substituting dashes for spaces).
prepopulated_fields doesn’t accept DateTimeFieldForeignKey, nor ManyToManyField fields.



If everything is well set up, whenever the user create a blogpost, for example, the title:

title = 'My first blog post'

A slug will be created automatically, something like: 'my-first-blog-post'

And we can read that blog post by accessing the url: http://mydomain.com/my-first-blog-post/


You will see it very useful if your Django project need to be implemented the blog functionality.

References:
"Practical Django projects" by James Bennett.
https://docs.djangoproject.com/en/dev/ref/models/fields/#slugfield
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields