Union Of The Snake, Part 1

C'mon ,you know that Duran Duran kicks ass! I was trying to think of a catchy title for a series of posts as I wind my way through the building of my first Python app, using the Django framework. If you've used any other framework, you should be able to follow along with these posts as the concepts are all pretty much the same.

First off, I have great hopes that the current CakePHP 1.2 manual can morph into a resource as great as The Django Book, which looks to me to be the essential resource for anyone wishing to start off with Django. Everything I'm doing at this stage in the project builds on what I've covered so far.

Anyway, I've chose to build out Rallyhat, my sporting road planning site. Much like when I build a CakePHP app, I start out with the models. Django has a pretty good ORM component, as compared to the associated data mapping model that CakePHP uses. Now, to paraphrase from the Django book: "introspection is hard", so in order to give the Model ORM some help you define the fields you will be using in your models. Here are the definitions I'm using:

PYTHON:
  1. from django.db import models
  2.  
  3. class Sport(models.Model) :
  4.     name = models.CharField(max_length=30)
  5.        
  6.     def __str__(self):
  7.         return self.name
  8.  
  9.  
  10. class Team(models.Model):
  11.     name = models.CharField(max_length=30)
  12.     sport = models.ForeignKey(Sport)
  13.     city = models.CharField(max_length=30)
  14.     state_province = models.CharField(max_length=30)
  15.     country = models.CharField(max_length=30)
  16.  
  17.     def __str__(self):
  18.         return self.name
  19.                
  20.                
  21. class Game(models.Model):
  22.     home_team = models.ForeignKey(Team, related_name='home_team')
  23.     away_team = models.ForeignKey(Team, related_name='away_team')
  24.     start_date = models.DateTimeField()
  25.     sport = models.ForeignKey(Sport)
  26.    
  27.    
  28.     def __str__(self):
  29.         return '%s vs. $s' (self.away_team, self.home_team)

As you can see, I'm able to define all my fields I'm going to use with generic data types, and can even define the associations between the tables. So, why do we do all this? Well, Django comes with some great CLI tools for helping you build stuff. In fact, I dare say that you cannot build a Django application *without* using these tools. Once you've defined the models you want to use, you validate the models using 'python manage.py validate', and it reports any problems it found.

While I was building this out, it told me that it couldn't determine the foreign keys I wanted, so I quickly figured out I had to put Sport first in the definition list, then Team, so that Game would know what to reference for the foreign keys. It also told me that I had to set a 'related_name' attribute for my foreign keys in Game since I was reference the same model twice for a foreign key. Very similar to how you can alias an association in Cake.

Okay, once that's done I can then get it to generate the actual SQL needed to create those models using 'python manage.py sqlall rh' (with 'rh' being what I'm calling the application within Django). In this case I'm using a Postgres backend, so it generated SQL specifically for Postgres.

SQL:
  1. BEGIN;
  2. CREATE TABLE "rh_game" (
  3.     "id" serial NOT NULL PRIMARY KEY,
  4.     "home_team_id" integer NOT NULL,
  5.     "away_team_id" integer NOT NULL,
  6.     "start_date" timestamp WITH time zone NOT NULL,
  7.     "sport_id" integer NOT NULL
  8. )
  9. ;
  10. CREATE TABLE "rh_sport" (
  11.     "id" serial NOT NULL PRIMARY KEY,
  12.     "name" varchar(30) NOT NULL
  13. )
  14. ;
  15. ALTER TABLE "rh_game" ADD CONSTRAINT sport_id_refs_id_66e4cc9c FOREIGN KEY ("sport_id") REFERENCES "rh_sport" ("id") DEFERRABLE INITIALLY DEFERRED;
  16. CREATE TABLE "rh_team" (
  17.     "id" serial NOT NULL PRIMARY KEY,
  18.     "name" varchar(30) NOT NULL,
  19.     "sport_id" integer NOT NULL REFERENCES "rh_sport" ("id") DEFERRABLE INITIALLY DEFERRED,
  20.     "city" varchar(30) NOT NULL,
  21.     "state_province" varchar(30) NOT NULL,
  22.     "country" varchar(30) NOT NULL
  23. )
  24. ;
  25. ALTER TABLE "rh_game" ADD CONSTRAINT home_team_id_refs_id_20e54e34 FOREIGN KEY ("home_team_id") REFERENCES "rh_team" ("id") DEFERRABLE INITIALLY DEFERRED;
  26. ALTER TABLE "rh_game" ADD CONSTRAINT away_team_id_refs_id_20e54e34 FOREIGN KEY ("away_team_id") REFERENCES "rh_team" ("id") DEFERRABLE INITIALLY DEFERRED;
  27. CREATE INDEX "rh_game_home_team_id" ON "rh_game" ("home_team_id");
  28. CREATE INDEX "rh_game_away_team_id" ON "rh_game" ("away_team_id");
  29. CREATE INDEX "rh_game_sport_id" ON "rh_game" ("sport_id");
  30. CREATE INDEX "rh_team_sport_id" ON "rh_team" ("sport_id");
  31. COMMIT;

Man, it creates the indexes too! Okay, now that I'm happy with that all I have to is 'python manage.py syncdb' and it goes and actually creates the tables (and indexes) for me. I took a look at the 'schema' task that exists for the Cake console (try 'cake schema' if you have already configured the console for use and poke around) and it will do similar things for you. Nicely done, gwoo!

(chartjes@jackjack ~/Sites/rallyhat)
>python manage.py syncdb
Creating table rh_game
Creating table rh_sport
Creating table rh_team
Installing index for rh.Game model
Installing index for rh.Team model
(chartjes@jackjack ~/Sites/rallyhat)
>

Bingo, presto! We have our tables created for us!

I hope you've enjoyed this little glimpse into Django (and how it relates to CakePHP, in an obtuse way I guess). Next time we invoke the spirit of Duran Duran, I'll be showing how I built a search form to find all games for a particular team, showing how Django's MTV (Model-Template-View) system works.

Article Tags >> || ||

5 Responses to this post.

  1. Stephen Orr's Gravatar

    Posted by Stephen Orr on 03.01.08 at 10:40 pm

    Yup, I've played with Django too. Love the Django book also, like you I hope the CakePHP manual one day gets that good (it certainly doesn't hurt their cause to have it).

    I ultimately gave up trying to use Django because my current webhost doesn't support it, and I'm not interested in paying out just for the sake of having one that does. It is nice though, very nice in fact.

    Interestingly, in Django they seem to have taken out a lot of the "magic" that we currently have in CakePHP, in favour of getting you to specify exactly what you want it to do. I'm not sure about this approach, but it certainly didn't get in my way during development of my practice applications.

    I absolutely love their templating system, which I'd like to steal for Cake but I'm just not skilled enough to develop it. renderElement goes a long way towards providing the functionality but not quite as far as their stuff.

    Given the current backlash against RoR, if the exodus continues there will be a bunch of people changing over to the likes of Django and CakePHP. Sounds good to me!

  2. kevin beckford's Gravatar

    Posted by kevin beckford on 03.01.08 at 10:40 pm

    Nice article indeed man! I'll have to agree about the magic stuff... when I was a perl guy i loved the Aslanian "Deep Magic" , but I was younger then. Now I want to know what I see is what it is. I've got no time to enjoy ( ahh the cool mists of memory ) a solution subtle yet complex, full of strange turns and curiosities.

  3. Nate's Gravatar

    Posted by Nate on 03.01.08 at 10:40 pm

    I have been playing around with django recently as well. The configuration isn't too difficult, but not nearly as pluggable as cake. The py-mysql library doesn't compile properly on 10.5 out of the box and even the hacks to get it working never seemed to work for me. I eventually just moved to sqlite just for playing around.

    I don't like that you can't migrate the DB from your model definition. You have to both define your fields in the model and in the DB any time you make even the smallest change. I guess that is some of the missing magic you spoke of.

    Even though I like some of the aspects of cake better, I do enjoy some things about django. The standout features are: the amazing admin interface, the use of python, the great docs and the miniscule amount of code required to do large tasks. I still have a lot to learn, but it's a great framework.

  4. speedmax's Gravatar

    Posted by speedmax on 03.01.08 at 10:40 pm

    As a big time CakePHP lover, I too love django's approach to different things.

    @Stephen Orr - actually i have ported django's template engine to php, tags, filters, blocks, template inheritance, you know the whole she bang, PLUS it compiles into native php code. its pretty much under the radar.. expect more to come soon.

    H2O template engine.
    https://svn.idealian.net/h2o/branches/0.2

  5. rtconner's Gravatar

    Posted by rtconner on 03.01.08 at 10:40 pm

    As far as templating (if you like templates)... why not just use the smarty integration to cake?

    Anyways, yeah I love Django. I think cake could learn a lot from it (glad to see you tried it nate). Django just almost completely ignores RoR in many ways, and IMO is much much better for it.

Respond to this post

Want to advertise on this blog? Send email to chartjes@littlehart.net
GTcars Canadian Car Audio TurboDodge Audi Forum
Mustang Forum Dodge Intrepid Miata Turbo
GTscene Pontiac Bonneville