Reader Feedback: Experiences With Django

Welcome to Day 2 of my answering reader feedback questions here in the month of August. I was asked to share my experiences with Django. I will confess that I am a complete n00b when it comes to Python (wrote a few scripts for work-related stuff) and got an early alpha of my baseball road-trip planning site actually working using Django. Sure, it was ugly and very rough around the edges but I got it to work. But I will say this: if I had the opportunity to start working with Python and Django every day (and for the same pay I’m getting now) I would take it in a heartbeat. Seriously.

So why all the love for Django and Python? As a guy who’s used PHP for a very long time, I’m really blind to the syntax of it. All the griping about needle vs. haystack and “PHP is ugly” is just wasted on me. Just so much pissing and moaning by people who should know better and lack the courage to learn the language they way they should. I heard it described by Evan from Identi.ca as being “the working man’s language”. Nothing wrong with that, as PHP is great at Getting Things Done. But Python…Python is vastly different from PHP. It’s about objects. It’s about consistency. It’s about the most amazing interactive interpreter I’ve seen since I was a kid fooling around on my VIC-20 typing in programs from Compute! magazine. Bet you didn’t think I’d been using computers for that long. To shift into bragging mode, I first got paid for programming when I wrote a program for my mother’s school (she’s a teacher) to create the salary grid for the teachers. I was 12. I think.

Also, there’s a dirty little secret about using frameworks that nobody really tells you. After a while, it makes you lazy. You forget how to do certain things because, well, the framework does it for you. The other day there was a tweet from someone asking about the best way to sanitize data before you put it into the database. My first thought was “sheesh, that’s built into the framework” and then I stopped myself and said “you are getting goddamn lazy!”. My response was “try using mysql_real_escape_string(…)” but was also told about using PDO’s binding of parameters as another way to do it. See, those things are all done by the framework meaning lazy old Chris doesn’t have to remember how to do it. Until the time he’s confronted with non-framework code that he cannot simply rewrite as part of a framework. *gulp*. So, since Python and Django are so different from the other frameworks I’ve used it forces me to STOP being lazy and actually learn how not only Django itself works but how the insides of it work as well.

Now, being an old hand at frameworks means using Django is not that big a stretch. I spent a lot time googling around for the “Python (or Django) Way” to do things. Except for a few concepts that are not familiar to a long time PHP guy (generators?) it wasn’t that hard to get up and running with Django. The documentation is awesome, and once you learn to stop writing PHP code in Python and instead embrace doing things the Python way, it becomes a lot easier.

In the end it’s still datasource-backed models talking to some controller code and passing it onto some template. I find the Django templates to be very limiting after my initial experiences and my “PHP is the template” background, and I think that as I get deeper into it I really have to find out how to do things the Django way. What CakePHP calls Model-View-Controller, Django calls Model-View-Template, but it’s really the same thing.

When I compare Ruby to Python, I don’t get the feeling that I will have to resort to dynamic functions and closures to Get Things Done in Django like I see happening in Rails. Besides, they seem to be two very different communities. That’s probably because the leaders of the Django community are so different in temperament and I don’t see the same type of “Django rules, everything else sucks!” mind sets that I saw in the Rails community. Maybe I’m just looking in the wrong places, but I feel more at ease in the Django community than the Rails community, albeit from the outer fringes of it.

So don’t be lazy and complacent about the tools that you use. Go and checkout Django and you might feel the same way about it as I do.

Article Tags >> || ||

Building Rallyhat: Importing Schedules

I continue to be impressed with Django as I build out Rallyhat. I have an extreme alpha version working on my laptop, minus the Yahoo! Maps stuff I've been playing around with. The biggest task was populating my database with the schedules for all the baseball teams. I thought I'd share what the import script looks like:

PYTHON:
  1. #!/usr/bin/env python
  2. from django.core.management import setup_environ
  3. import settings
  4. setup_environ(settings)
  5. from rallyhat.www.models import Team
  6. from rallyhat.www.models import Game
  7. from rallyhat.www.models import Location
  8. from rallyhat.www.models import Sport
  9.  
  10. from datetime import date
  11.  
  12. import csv, urllib, time
  13.  
  14. s = Sport.objects.get(name='Major League Baseball')
  15. teamSchedules = Team.objects.all()
  16.  
  17. for teamSchedule in teamSchedules:
  18.     scheduleFile = teamSchedule.schedule
  19.     print "Importing games for " + str(teamSchedule.name)
  20.  
  21.     if scheduleFile != "":
  22.         reader = csv.reader(urllib.urlopen(scheduleFile))
  23.  
  24.         for row in reader:
  25.             teams = row[3].split(' at ')
  26.  
  27.             if len(teams) == 2:
  28.                 if Team.objects.filter(name=teams[1]).count() == 0:
  29.                     print "Adding new team: " + teams[1]
  30.                     homeTeam = Team(name=teams[1], sport=s)
  31.                     homeTeam.save()
  32.                 else:
  33.                     homeTeam = Team.objects.get(name=teams[1])
  34.  
  35.                 if Team.objects.filter(name=teams[0]).count() == 0:
  36.                     print "Adding new team: " + teams[0]
  37.                     awayTeam = Team(name=teams[0], sport=s)
  38.                     awayTeam.save()
  39.                 else:
  40.                     awayTeam = Team.objects.get(name=teams[0])
  41.  
  42.                 gameDate = time.strftime("%Y-%m-%d", time.strptime(row[0], "%m/%d/%Y"))
  43.                 startTime = time.strftime("%H:%M", time.strptime(row[2], "%I:%M %p"))
  44.  
  45.                 # If this game doesn't exist, add it to the system
  46.                 if Game.objects.filter(home_team=homeTeam, away_team=awayTeam, game_date=gameDate, start_time=startTime).count() == 0:
  47.                     locationCheck = Location.objects.filter(name=row[4]).count()
  48.  
  49.                     if locationCheck == 0:
  50.                         print "Adding new location: " + row[4]
  51.                         l = Location(name=row[4])
  52.                         l.save()
  53.                     else:
  54.                         l = Location.objects.get(name=row[4])
  55.  
  56.                     locationId = l.id
  57.                     g = Game(home_team=homeTeam, away_team=awayTeam, location=l, game_date=gameDate, start_time=startTime)
  58.                     g.save()

It's interesting to treat everything as an object after so many years of being in the PHP world where you can mix and match depending on what's been going on in your application. I'm also amazed at how clear the code is. There is some non-intuitive stuff in there, especially when dealing with the saving of model records. It took me a while to figure out I could pass the object containing the model as a parameter when saving a record for a model that it is associated with.

Article Tags >> || ||

What’s In Chris’ Brain: March 2008 Edition

I've got a whole bunch of little things I want to talk about, as opposed to one big topic. Here we go

  • You'll see a badge on the right side of my blog announcing that I'm speaking at Open Web Vancounver 2008. If you can make your way up to Vancouver on April 14th and April 15th, please come up and support this conference.
  • I got an email from someone on the CakePHP mailing list asking me about what sort of setup I have for running my apps. I have a 256 MB slice with slicehost, and I have ZERO complaints about performance. I'm running PHP 5.2.5 under fastcgi (I use nginx as my web server), with MySQL on there to power my blog. In an earlier post I wrote how to create the rewrite rules for CakePHP to work with nginx, so search my archives for that. I've got Python on there as well for my upcoming Django work, and soon Apache will be on there to act as my app server for Django.
  • Wrote my first Python script for work: it trolls through a bunch of gzipped XML documents, doing some search and replace. 75 lines of pure Python n00bness, built entirely with the help of "Dive Into Python" and google. I'm sure it could be optimized by some more experienced Pythonistas, but it sure felt good to get the first one done and out of the way.
  • I've decided to start using twitter again, see how long that lasts
  • The more I use it, the more powerful I realize jQuery is
  • Some ruthless refactoring has caused my Code Igniter code to be a bit more CakePHP-like, in that I'm moving stuff into models and out of the controller wherever it makes sense. That's a good practice no matter what framework you use
  • As much info as there is out there for using Django (the Django project site, the Django book available online), it sure would be helpful to me to find some sort of Django guru who can help me out with some of the finer points of Django and Python itself. I'm trying very hard to not write Python code like I was writing PHP, and I feel like some of the finer points are escaping me.
  • I'm working on moving some old CakePHP code I have that runs on PHP 4 over to PHP 5, and having PHP 4 *and* PHP 5 running on the same server. Should be an interesting experience
Article Tags >> || || || || ||

Building Rallyhat: First Steps

This will be the first in a series of posts chronicling my building out of Rallyhat, a site that people will use to plan sporting road trips, baseball first. In this first installment I wanted talk a bit about the first steps I too to actually get this thing rolling.

Now, I could easily build this site in CakePHP, so that's not really much of a challenge. I already have one site that runs Cake to keep me on top of things there, and future work-related projects are going to be CakePHP for me as well. So, something else then? I already did the Rails thing, and tore that down to build the CakePHP one. I thought about using Merb, and I'm going to attend a talk at Open Web Vancouver about Merb so I get a better idea about what it could do for me. So that left just one choice.

C'mon, you're not really surprised are you?

One of the things I really liked about Django is the admin app that you get for free. I've already been using it to full some of my support tables for the application, but I wanted to talk about a neat little thing you can do here. In Django, you define the names of the fields in your model in order for the ORM magic to work. Here's a little sample:

PYTHON:
  1. from django.db import models
  2.  
  3. class Sport(models.Model):
  4.     name = models.CharField(max_length=30)
  5.    
  6.     class Admin:
  7.         pass

The Admin stuff is so that those models show up properly in the admin part of the application. So, just like in CakePHP where you can use $this->Model->find('list') to get an array for use in your dropdowns for forms. Django, does this a little differently.

Being totally object oriented, if you drop into the Python interpreter and ask it to return a model to you, you'll get something like this, taken from the Django tutorials:

PYTHON:
  1. (chartjes@jackjack ~/Sites/rallyhat)
  2. >python manage.py shell
  3. Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
  4. [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
  5. Type "help", "copyright", "credits" or "license" for more information.
  6. (InteractiveConsole)
  7. >>> from rallyhat.www.models import Sport
  8. >>> Sport.objects.all()
  9. [<sport : Sport object>]
  10. >>>

WTF? What good is "Sport: Sport object" to us? I want something more descriptive. How about the name of the sport? That's easy. We can modify the Sport model and tell it that when we return the object, return the "name" field instead.

PYTHON:
  1. class Sport(models.Model):
  2.     name = models.CharField(max_length=30)
  3.    
  4.     class Admin:
  5.         pass
  6.    
  7.     def __unicode__(self):
  8.         return self.name

So, when I drop into the shell, I get the following:

PYTHON:
  1. (chartjes@jackjack ~/Sites/rallyhat)
  2. >python manage.py shell
  3. Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17)
  4. [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
  5. Type "help", "copyright", "credits" or "license" for more information.
  6. (InteractiveConsole)
  7. >>> from rallyhat.www.models import Sport
  8. >>> Sport.objects.all()
  9. [<sport : MLB>]
  10. >>>

Same result, different way to get to it.

Article Tags >> || ||

I’m An Editor Waffler

Taken from a discussion with my friend Kevin via IM earlier today (warning, may contain bad language):

webslinginfool
or try pida
which _is_ what you wanted no?

Chris Hartjes
pida?

webslinginfool
*sigh*

Chris Hartjes
not really

webslinginfool
http://pida.co.uk/files/screenshots/pida_0-5-2_17.png

Chris Hartjes
if I want that, I can go with Textmate

webslinginfool
true
very true
actually , why dont you use textmate?

Chris Hartjes
I do use it
but you get me looking at that vim stuff

webslinginfool
ahh
a man of weak faith
tsk
tsk
tsk

Chris Hartjes
very weak when it comes to editors

webslinginfool
wait, let me halt construction of your monument
i've never met anyone like you actually

Chris Hartjes
in what way

webslinginfool
editor waffling

Chris Hartjes
yeah, that's pretty rare
I dunno why I'm like that

webslinginfool
i've never even  heard of it
you should totally add an "editors"
section to your blog and simply detall
your experiences
oh, and make friends with a bishop

Chris Hartjes
fuck
YOU

webslinginfool
because you'll start a holy war!

Kevin is a vim guy, and is always giving me tips (solicited or not) on how to make my vim experience more enjoyable. A lot of what he gives me *is* useful. I probably have a vim setup now that will work okay for me, and I did give vim a two-week audition as my main editor a while back. However, it didn't have the GUI file drawer / file explorer crutch that I've gotten used to. Besides, I think my arguments about why I use each editor are just lame.

  • Komodo - got a free license after talking at the Vancover PHP conference last year (please, go to Open Web Vancouver this year so they can get enough money for me to fly business class ;)), cool editor, nice debugger...but I find it slow and unresponsive at times.
  • TextMate - one of the first OS-X apps I ever paid for, nice and snappy, great syntax highlighting...but doesn't have the tooltip stuff that Komodo does. I did find a cool plugin that shows me what files I've modifed in version control right there in the file drawer, but it's not an IDE like Komodo is
  • vim - very powerful, pretty much does everything I need in an editor...but all those damn commands to remember, and where's my pretty GUI file explorer?!?!

Those are three of the lamest statements I've come across in my talking to people about the editor I use. Editors are usually a religious issue amongst developers: you can pry the one they use every day from their cold, dead hands.

So, maybe it's time to grow up as a developer and stop switching between editors. But can I do it? Yes, I know you're not used to reading my angst-filled posts about what editor to use. Damnit, why am I so weak on this issue?!?

This post is not intended to become a holy war on what editor to use, I'm just expressing my frustration at my inability to decide what to do here. If I look at it objectively, it's about what tool I would be the most productive in. The problem is, I can't figure that out...probably because I keep switching all the damn time.

Is it fear of commitment? Fear that I pick the wrong editor for what I need? I have started branching out into other languages, so my editor needs to support those as well. All three can do it. *sigh*

Komdo vs. TextMate vs. vim. Maybe there is no winner, just a loser. Me.

One of the thing the Pragmatic Programmers said (when not trying to get us to buy their books all the time) is to settle on one editor, whatever one that is, and learn ALL it has to offer because you might be surprised what it can do for you. Flipping back and forth is no way to do that. More like a delaying tactic from someone who doesn't want to HAVE to pick, maybe?

Well folks, that day has come. I must pick and stick with it for once. I'll let you guys know at the end of the week what I picked. Go back to making fun of me in the other posts, okay?

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


@TheKeyboard is Digg proof thanks to caching by WP Super Cache!