Andy Loughran

Django FormWizard and Formsets

I've finally got round to doing a bit of coding in Django to help produce useful applications for the charity that I'm visiting out in India. So far it's been a pretty painfree experience, and I'm learning more and more about django, which is speeding me up no end.

One of the applications that I'm writing at the moment is an online application form for future volunteers.  I've written out a model for each of the categories of information that I need to collect, and have created a template and view for displaying that information for end-users.  I also have a view for those people that are logged onto the admin interface for viewing each of the volunteer applications.

However, I believe there are a few shortcomings in my design that I want to overcome.  The first is that with each separate model I have linked it back to the original CoreInfo model (containing the volunteer's name) using a ForeignKey.  I'm not sure this is the best way to do this, so please advise if you can tell me a better way.

class CoreInfo(models.Model):
full_name = models.CharField(max_length=100)
preferred_name = models.CharField(max_length=100)
dob = models.DateField()
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
email = models.EmailField()
healthy = models.BooleanField()
home_address = models.ForeignKey('Address'related_name='home_addr')
term_address = models.ForeignKey('Address', related_name='term_addr')
def __unicode__(self):
return self.full_name

class Address(models.Model):
flat_number = models.PositiveIntegerField(blank=True,null=True)
flat_name = models.CharField(max_length=100, blank=True, null=True)
number = models.PositiveIntegerField()
road = models.CharField(max_length=100)
town_city = models.CharField(max_length=100)
county = models.CharField(max_length=100)
post_code = models.CharField(max_length=10)
country = models.CharField(max_length=100)
def __unicode__(self):
return '%s %s' % (self.number, self.road)

The second problem I have is that in four of the models, I require the end-user to enter in an Address.   Rather than having to retype all the address fields twice, I created an Address class and have linked CoreInfo to it by ForeignKey.  However, I want the user who is accessing the form to only be able to access Addresses from the drop-down that they themselves have entered.  I think I can do this using django sessions, and adding the random session value to the address field, and then filtering the choice list by whether it contains the ID of the session.

The main problem I have is organising this in a forms.py though.  I'm using FormWizard to iterate through each of my forms, and in doing so appear to have lost fine-tuned access to displaying the home_address and term_address fields.  I'd like to know where to edit their attributes, as I'd want a popup for adding a new address as is done in the admin.  Chances are the term_address might match the home_address, so the drop-down box (current view) with the green '+' would be perfect.

Hopefully someone who's django fu is strong will be able to advise me; I wait in joyful anticipation.

Twitter, Psychology, and if I was 3 years younger...

Twitter.  It's one of those things that people don't 'get' until they try it.  You update your status in 140 characters at multiple points during the day with events as mundane as feeding your cat.

However, twitter has become more than this.  Unfortunately, I've not been using it long enough to see it's evolution, but there are a could of 'extra' functions that end-users have created which help organize this mountain of information.  My handle on twitter is 'andylockran'; if someone wants to address a message in my general direction, but wants others to join in the conversation, they'll prefix the message with an @.  If they want it to be sent to me in private, it'll be prefixed with a 'd ' - and if they're talking about a general topic, that others could also be talking about, it's prefixed with a #.

Whilst I was at university, one of the assignments set was to examine the level of information that people were happy to publish about themselves on Internet forums.  This was in 2004, with the heyday of the 'Internet forum' being the mid-late 90s.  It was an interesting task though, as it was pre-'general release' facebook and I didn't go to a University esteemed enough to be included on facebook until just before the 'general release.'

One of the things we noted was that people were able to put so much personal information of forums, and much of it was irrelevant to the particular topic being discussed - but by putting it out there people were dealing with their issues.  Rather than holding information inside and trying to repress it; publishing this information was a form of therapy.  With twitter, it's easy for anyone to publish information and with something as simple as a # sign, you can immediately converse with a group of people who have a shared interest. I don't use them alot, but being able to access a group of people attending the current CES show, I just type #ces or #ces09.  There are even sites that scan the blogosphere looking for these tags - so hopefully if someones demonstrating this in Vegas, they may accidentally stumble across this blog!

Something I've blogged about before, is the idea of the 'Long Tail' - Chris Anderson. This is where people who would have been seen as uneconomically viable in production of a capitalist nature are now able to contribute, no matter how small their contribution, in an economically viable way.  Their contributions may be small, but their combinations may unlock something much bigger.  With the information and infrastructure afforded to twitter users, it is no longer 'taboo' to try and get in touch with someone else suffering from a similar ailment.  Tag your posts with the ailment, search for people by location, and you've immediately found yourself a local community and therapy group.

The ability to do things like this is unprecedented, and we're moving at such a fast pace that there is rarely a week goes by when I realize I could have used the Internet to do something more powerful that I would have ever thought. It also helps that the tools for manipulating this information are getting easier.  python-twitter is a very easy api to learn.  When you put that with ipython; a python shell that provides tab completion, and a useful help() feature, I could put most of my peers in front of a computer and get them to download and create graphs of tags .etc from the twitterverse. with little tuition.

The other thing regarding twitter, is that you get a three dimensional view of issues, both quantitatively and qualitatively.  If you want to grab a load of stats for illnesses, there's so much information out there passing through the RSS feed every minute, that doing so for a week would give you a massive sample of information.  Conversely, you can pick one person from that feed and analyze their twitters longitudinally.  Because all the information is in the public domain, this is entirely legal.

So if you're a psychology student now, sitting down to write an essay on psychology and the internet - may I suggest you take a look at twitter, as it's almost the perfect platform for this sort of work.   I wish I had.

Pinax

Thanks to listening to the #ubuntu-uk PodCast - I came across this little gem.

Pinax Project

It's a collection of reusable django apps - all designed to be reusable - together.

What this means?

This project needed a critical mass to get it off the ground.  Basically the way things are referenced across all the apps need to be the same.  There's no point having two reusable apps.. if they both require different ways of interfacing with the same object.  They break if one has 'name' as being fullname, and ther other requires name to have two separate name fields (for firstname and lastname).  You've then got to write a way of getting around this problem, which just increases as more features were added.

Well, the neat guys over @ pinax have started up a project on creating re-usalble apps that sing of the same hymnsheet - and they look awesome.  Having watched a presentation on youtube, the following phrase (quoted) stood out for me:

"If you want a man to build a boat, do not send him out for wood and nails, but teach him to yearn for the wide and endless sea." -Antoine St Exupery

It's really accurate for these kind of projects - writing reusable apps off some other guys prescribed instructions doesn't fill the heart with glee - but seeing what can be achieved by doing this makes you want to contribute.

So Cloud27 was born - it's a social network, but made up of the componenets developed on pinax - meaning you get to play with what you're about to download an integrate into your own project.

It looks really good, and there's a project I've been meaning to do which has been yearning out for a kickstart - I think this may have just done it!

Django League Table

I'm trying to write a league table for some sport results using django.  At the moment my model looks pretty basic:

class Scores(models.Model):    matchnum = models.AutoField(primary_key=True)    homeuser = models.ForeignKey(User, related_name="hmuser")    hometeam = models.ForeignKey('teams', related_name="hmteam")    homescore = models.IntegerField()    wayuser = models.ForeignKey(User)    awayteam = models.ForeignKey('teams')    awayscore = models.IntegerField()    pub_date = models.DateTimeField(auto_now_add=True, editable=False)    def __unicode__(self):        id = str(self.matchnum)        return id    class Meta:        verbose_name_plural="Scores"class Teams(models.Model):    teamname = models.CharField(max_length=40)    def __unicode__(self):        return self.teamname    class Meta:        verbose_name_plural = "Teams"

However, with the information in this simple model - I should be able to generate a league table, with the following fields:

TeamPlayed #WonDrawnLostGoals ForGoals AgainstGoal DifferencePoints

So how to put this into a Django App? Well I need some advice, as my original method was to edit the save() function of the model to input fields into a new model - however, I should be editing things at the form level. I'd also like a 'generate league' method, rather than a method where a league is generated at the end of each score addition. The main advantages of this approach is that I can:

  • Generate the League from existing score data.
  • Future Users can generate the League from their data.
  • Leagues can be generated at the end of each 'gameweek' - rather than just at the end of each game.

Django is a fantastic python framework that I'm immediately getting to grips with - but as this kind of application (simple as it is) - is one that's scalable and may be useful to many other users.. I want to get it right from the start.

I'll be tagging the posts with 'djangoleague' if you want to keep up with development - and if anyone wants to use the project/help me out with it - please post in the comments and I'll get back to you.

My programming career begins (with bugfixing).

It's taken me a while, but just over 12 months learning the basics of programming, I'm finally contributing and commiting code to my company's SVN repo.

One of the things I like about programming, is that it seems to suit me.  Having not done any programming at all before 12 months ago, jumping in at the deep end and going into a career that requires it wasn't an easy step to take.  However, I've had some good guidance from my colleagues - in that I've not settled upon a single language.  I wouldn't say I know any language well, but I'm reading and understanding code better than I've done before.

The hardest part for me, is looking at a problem and seeing my own solution - rather than the solution that's coded infront of me.  Once I've understood the train of though of the original programmer, it's alot easier.. however, at the start I was failing to do that.

At the moment I'm happy making modifications and bugfixes to programs.  It's simply enough stuff, where auditing and testing the problem takes by far the majority of the time.  However, I'm understanding things better - and feel like I'm finally making some decent progress.

I know it's possible to contribute to open source in other ways than just coding (I've been doing that for the last few years) - but now I'm coding I hope to submit code to the projects I like.  It's been my aim for a while.  I've set up my bzr repo, but most of my code at the moment I'd hope to submit as patches to other projects.  Who knows what the future will hold.