Archive for February 2009

Altering a Django project to migrate from a simple ManyToMany relation to one with extra information

There are still quite a few features which could be useful on Clusterify. One I thought could help in structuring projects is the concept of Roles: a way to let users joining a project specify which role they want to take in it.

Now, most common tasks are made amazingly easy with Django. Changing models, while probably common, seems very tricky to automate right, though (and anyway would you trust the automation logic to make the right changes?). Yet there’s dmigrations which I need to try one day.

Back to the original problem: Roles. Formerly we had a ManyToManyField in the Project model linked to the User model for users joining a project. In the background, Django creates a table to hold the relationship named after the field (projects_project_joined_users).

The way to add extra information to a relationship, in the Django ORM, is with the “through” argument to the ManyToManyField, which lets you specify a model which will hold the relationship. In this case, we’d get:

class Membership(models.Model):
    user = models.ForeignKey(User)
    project = models.ForeignKey(Project)
    role = models.CharField(max_length=120)
    approved = models.BooleanField(default=False)

and in Project we now add the field:

    members = models.ManyToManyField(User, through='Membership')

This would create a table named projects_membership. It still doesn’t hold any data, though. Now I see two ways of making this change in the DB:

  • Renaming or copying the old table holding the relationship, and ALTERing it until it looks like that new one.
  • Creating the new table (by looking at the output of sqlall) and filling it by copying over the data with a mapping of fields.

I chose the later, which seemed more straightforward (and anyway I have other manual copying operations to perform). There’s an easy way to copy over the data, the INSERT … SELECT syntax in SQL. The old table was named projects_project_joined_users, so the syntax becomes:

INSERT INTO projects_membership (user_id, project_id, role, approved)
    SELECT projects_project_joined_users.user_id, projects_project_joined_users.project_id, '', 1
    FROM projects_project_joined_users;

Running this copied over the old data, and now the code may be updated. Note that I had first created the new table by checking the output of “sqlall” and running the relevant statements (CREATE TABLE, ALTERs for foreign key constraints, and index creation).

It’s now more complicated to handle the relationship this way, though, as one can’t use add() or remove() as before. Take a look at the doc for more info on this.

Clusterify project: word cloud bookmarklet

This is a separate post, but it’s another quick project I suggested, among the first batch I wrote as I brainstormed to get a little bit of content to get Clusterify going: a bookmarklet script to display a word cloud based on all the text in a page. The utility might be limited, but it was fun to code. Here’s the source (bookmarklet code is given in a comment) and here’s a screenshot of what it looks like:

Clusterify project: Delicious tags userscript

I’m doing a few Clusterify projects, to test the site and concept at the same time. A very quick project suggested by member psytek concerned adding popular/recommended tags automatically on Delicious with a Greasemonkey script. Turns out it took me around 10 lines of code, gave me a good excuse to finally learn about XPath, and it’s quite useful. Here’s the script over at Userscripts.

Just launched — small project meetups site for programmers

Here’s the project I’ve been working on for the past 3 weeks with another programmer named Aneesh: .

It’s a site on which you send project proposals, usually very short in time demand (2 hours is suggested), and through them you meet other programmers.

I can’t spend too much time writing a two-volume novel about it for the moment, as the launch is still ongoing, but here’s the launch thread on Hacker News.

Links: discovering and following key social media resources for a given topic

In my introductory article on RSS, I mentioned that fundamental to a good information diet is following the right sources. Here’s an article on ReadWriteWeb that shows you a method on how to do just that: find the top blogs for a given topic (niche). It compares different ranking systems for blogs.

Once you’ve read that, you might want to check out this other article, which builds on the first one and shows you how to find the most relevant knowledge the set of results you’ve come up with. In essence, it uses AideRSS’ PostRank to find the best articles in the list of blogs you’ve come up with, and shows you how to use Google Custom Search to build a custom search engine that searches only those top sites you’ve found.