Adding tagging to your Django application is easy, but can have some complications if you have existing data. In this post, I will cover how I accomplished it on this blog.

The first thing to do is install django-tagging. I am using Django 1.0, so I have to get the code from their subversion repository. You will not have to do this once version 0.3 comes out. Once django-tagging is installed, we can add tagging to our INSTALLED_APPS in our settings.py and do a ./manage.py syncdb. That's all you have to do for basic functionality in django-tagging. You will want more than basic functionality, am I right?

The next step you will want to take is registering your models with tagging.register as shown below.

import tagging
from django.db import models

class Entry(models.Model):
    # Imagine the rest of your Entry model here
    pass

try:
    tagging.register(Entry)
except tagging.AlreadyRegistered:
    # You might wonder what is going on here.
    # This is a bug in the svn release.  For some reason, the authors' cannot handle
    # re-registering gracefully, so we have to.
    # This should be fixed in later releases, but your code will still work here after it is.
    pass

After your model is registered, you will have access to several convenience methods and attributes, like yourmodelinstance.tags. It makes handling tags in your views and templates a dream.

What about Django's awesome admin though? It is a pain in the butt with just this to attach tags to a model instance. You have go to Tagged Objects, select the tag to apply to your model instance, select the model to be tagged, and finally the id of the instance. You do not want to do that. There is a smarter and faster way. We first need to add a TagField to our model like so.

import tagging
from django.db import models
from tagging.fields import TagField

class Entry(models.Model):
    # Imagine your other model fields preceded this
    tags_string = TagField()
    # Don't name this tags as it will conflict with the tags attribute gained
    # through registering the model with tagging

try:
    tagging.register(Entry)
except tagging.AlreadyRegistered:
    pass

If this is a fresh application without real data, you are done. You may not be so lucky, like myself. You will have to alter the database table yourself because Django, as great as it is, does not do this...yet. Here is something like commands you would run to alter your table, assuming your database is called yourdb, your application is called yourapp, your model is called yourmodel, and the last field of your model before tags_string is called last_field:

ALTER TABLE yourdb.yourapp_yourmodel ADD tags_string VARCHAR(255) AFTER last_field;
UPDATE yourdb.yourapp_yourmodel SET tags_string = '';
ALTER TABLE yourdb.yourapp_yourmodel MODIFY COLUMN tags_string VARCHAR(255) NOT NULL;

You can inject this into mysql easily by running something like this:

mysql -u root -p < file_the_earlier_sql_in

Now, your table is just like a fresh one, schema-wise. Your data is the same with a blank tags_string field. Tags can be added from the model edit page in Django admin now. I will cover adding tags to your views and templates in the next post.

Posted by Tyler Lesmann on March 6, 2009 at 9:26
Tagged as: django mysql python sql
Comments
#1 Ryan Blunden wrote this 2 years, 6 months ago

Thanks for this great tutorial. This will definitely come in handy when I implement tags in my applications.

#2 tingelt wrote this 1 year, 11 months ago

Thanks. This was handy for me!

#3 larcher wrote this 1 year ago

You might want to check out South -- it will handle all the ugly database migration for you whenever you change fields on your models.
Once you have it set up, those 3 lines of SQL become this:
./manage.py schemamigration <app> --auto
./manage.py migrate <app>

Post a comment