Loading...

Simple django-tagging HOWTO

January 25, 2008 1 Comment Tagged as: django django-tagging howto python

After looking through my Google Analytics results, I noticed that a few hits to my site were people looking for a howto on integrating django-tagging, which I have been wanting to write for quite some time. While I'm quite experienced working with SQL schemas and the like, there were some ORM concepts that I had never been exposed to until I started using Django (it was my first framework featuring an ORM). Things like Generics confused me, although I knew how to do something similar in plain ol' SQL, it took me a bit to grasp the concepts. So I figure a good way to demonstrate their uses, along with demonstrating integrating django-tagging into an app would be a fine use of my precious blog space...

Please keep in mind that I am not a Django expert, nor am I a django-tagging expert. My experience with django-tagging has been adding it to my blog posts. While I've considered making an entire category hierarchy-type site with tags, I haven't actually implemented it. All I can demonstrate on the basics. You'll have to learn the rest on your own. Also, it's important to point out that I have been using the svn version of django-tagging, although recently, a 0.2 version was released. I just set up my project's svn to use externals and keep me up to date on django-tagging.

First thing's first, you need a model. I'm going to use a dumbed down version of the model I use for blog posts. Lay out your model like this:

from django.db import models

class BlogPost(models.Model):

    title = models.CharField(max_length=30)
    body = models.TextField()
    date_posted = models.DateField(auto_now_add=True)

Now you have a pretty simple blog class. After a syncdb, you can fire up the admin app and start blogging! Er, kinda. You won't have any way for a user to see your posts, but you'll have posts in the database. However, you've got no tags! How would you implement tags into your new fangled blog? Easy. Download the tagging module and install it (I usually just copy the appropriate files to my $PYTHONPATH). Then it's actually quite simple, and you'll kick yourself for not figuring this out. Modify your blog model, and add this:

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

class BlogPost(models.Model):

    title = models.CharField(max_length=30)
    body = models.TextField()
    date_posted = models.DateField(auto_now_add=True)
    tags = TagField()

However, you're going to want a method in your model that will allow you to iterate through the tags, called get_tags. I also have a set_tags method, and I know there was a reason I added that, I just can't remember what it was... (a good case for why you should always comment your code). So modify your model so that it now looks like this:

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

class BlogPost(models.Model):

    title = models.CharField(max_length=30)
    body = models.TextField()
    date_posted = models.DateField(auto_now_add=True)
    tags = TagField()
    
    def set_tags(self, tags):
        Tag.objects.update_tags(self, tags)

    def get_tags(self, tags):
        return Tag.objects.get_for_object(self)      

Now you've got a full blown model with tagging built in. Make sure you've got tagging installed in your INSTALLED_APPS, blow out your database, and syncdb again. Hooray! You'll notice on my blog that I have the tags shown at the top of each post, which is accomplished by with the following template code:

{% for tag in blogpost.get_tags %}
  <a href="/blog/tag/{{tag}}" alt="{{tag}}" title="{{tag}}">{{tag}}</a>
{%endfor%}

I know there are template tags for many of the standard operations for django-tagging, but I haven't used any of them. I noticed that most of them are for tag clouds by model or object, and I would like a tag cloud period, with links to pages on the site with various items that are tagged with the given tag. I have just been far too lazy to actually implement it yet, but there is a weekend coming up...

Edit: I've found some better ways to implement django-tagging, so I've made some changes to this tutorial

Experience Renaming Deployed Django Apps

October 16, 2007 4 Comments Tagged as: django django-tagging howto refactoring

I've released yet another iteration of The Iron Lion, with the key of this new release being my new knowledge of the newforms library. I've been thinking about adding the ability to comment for a while, and have even blogged about some of the ideas I've had/seen to reduce spam and the like. You'll find the new contact form to be my experiment with the newforms library (and also a solution to putting my email out on the web, even though I've gotten plenty of spam in the email address anyway).

After I pushed this new version, I decided that my naming scheme for my various apps was becoming cumbersome more than clever. I was naming the different apps after planets in our solar system. Cute naming convention, but since this is becoming more than just a few apps, I found it difficult to remember what neptune was, why I need the earth app in this situation, and what pluto was even created for. So I obviously needed to rename these apps.

I was expecting that the process was just a matter of renaming the folders. There were obvious dependencies to worry about, and import calls to fix. So I started by moving the folders around. I then did an fgrep for all the instances of the old names. Using sed, I did a search and replace of each name. For some reason after that, my Django dev server didn't much like the environment variables I had set, and so I had to work out some problems with my environment before I could test it...

One day later, and I was back to work. I browsed around the dev server, to make sure everything was working, and noticed only one thing broken: Tags. This was an opportunity I had been waiting for, actually, and I dove headfirst into the tag database schema. The tags for this site are generated with the django-tagging app, and so I didn't have much experience with generic relations and the like, and I wanted to. I found a table called 'tagged_item' which I invesitigated, and found a reference to a content type id. I figured it must be the django_content_type foreign key, and kept digging. Apparently, django keeps a database of all the installed models, and the apps they are connected to. A few updates later, and I had tags working!

So, in summary, if you want to rename a Django app that's deployed in the field:

  1. Rename the folder found in your project root
  2. Change any references to your app in their dependencies, i.e. the app's views, the urls.py and settings.py files.
  3. Edit the database table django_content_type with the following command: UPDATE django_content_type SET app_label='<NewAppName>' WHERE app_label='<OldAppName>' (Note: for renaming models, you'll need to change django_content_type.name)