Archive for February, 2009

APIMuni by Danny Roa – Bringing NextMuni To The Masses

Saturday, February 28th, 2009

Danny Roa, whom I met at the last Django Meetup, has put out a quick API for accessing Nextbus data.

It’s hosted on the App Engine and can be found here.

His writeup is here.

He recycled the scraping code from yourmuni, props to him for giving props :) Of course, that just means that when Nextbus gets angry, they’re going to come after me first!

Developers don’t create API’s for nothing, so I am eagerly anticipating what Danny is going to use this API for.

Reusable Logging in Django Apps

Saturday, February 28th, 2009

I have 3 drafts sitting in my queue – 1 really long post and 2 short ones. I’ve been picking away at the long post on the shuttle rides, but in the meantime I’m gonna try to push out the two quick ones. This is one of the quick ones.

I was trying to figure out how to set up reusable logging in my apps and have it fairly decoupled from the overall project. Here’s what I came up with:

  1. Set up a logger object using these instructions in settings.py and store it in the LOGGER variable.
  2. Grab it inside apps using django.conf.settings like so:

from django.conf import settings
try:
    logging = settings.LOGGER
except AttributeError:
    import logging
Then just use logging.debug, logging.info etc. Thus, if a LOGGER is configured inside the project’s settings.py, we use that (django.conf.settings points to the settings.py for whatever project you’re working inside of, so you can move your app project to project no problem). Otherwise, we just use vanilla logging functions with the global logging configuration. Nice and sweet.

Suggestions on other ways to do this are, as always, welcome.

Example on django snippets: here.

Django Tip: Using Dictionaries For Model Method Parameters

Tuesday, February 3rd, 2009

I’ve been working a whole lot outside of my job, mostly writing Python and working with Django. I don’t have much energy for a real blog post about something awesome, but I do have a tip to share. Advanced “pythonistas” won’t be impressed, but I haven’t seen this documented prominently anywhere, so I’ll toss it up anyway.

As we all know, Python supports keyword arguments, and the Django ORM takes full advantage of this. When doing lookups, the ORM parses keyword parameters in order to determine what SQL query to execute. A typical ORM call will look like this:

all_oatmeal = Cookie.objects.filter(cookie_type='oatmeal')
That’s very cool and expressive. However, what if our search criteria depend somehow on user input? For example, what if we have a search form with multiple fields, but only want to search by the fields that a user entered something into.

We could have a series of convoluted if/else statements to determine which variables were set and have a corresponding .filter() call for each possibility, but that would be dumb, convoluted, and hard to read later. Also, dumb.

Instead, we can use an alternative way of passing keyword arguments provided by Python (details here): putting ** in front of a dictionary being passed to a function makes Python unpack the dictionary and pass the pairs as keyword arguments to the function. Using that technique, we can arbitrarily construct a dictionary of the search parameters, then pass it to a single .filter() call at the bottom.

An over-simplified example, in which I assume that our form fields match up exactly with model properties

for key in form_data:
    if form_data[key]=='':
        del form_data[key]
wanted_cookies = Cookie.objects.filter(**form_data)
I’m sure there’s a more elegant way to do the empty value stripping too, but that’s not our focus (comments on the subject are welcome, though, for to make me smarter). The point is this: this technique allows for very clean, easy to read, efficient code.

Creating model instances

cookie_data = {
    'cookie_type': 'oatmeal',
    'cookie_size': '3in',
    'cookie_touched': True
}
c = Cookie(**cookie_data)
c.save()
Obviously, this applies to more than just Django – there are many many use cases where this trick can come in handy. Enjoy!