Pitfalls When Upgrading to Django 1.4

The Sting

The Players

The Yipit Django team just finished the process of upgrading to the 6 week old Django 1.4 and figured that we would share the process we went through and some gotchas we found.

The Set-Up

Our goal in this process was not to start utilizing new Django 1.4 features, although there are quite a few. Our goal was to get our system running and stable on Django 1.4. Over the next few weeks we’ll start utilizing some of the new features (QuerySet.prefetch_related, ModelAdmin.save_related(), and queryset bulk_create). This post focuses on what is needed to get running on 1.4 - even though we’re dying to use some of the new features.

The Hook

Upgrading a critical piece of your stack is something that should never be done with haste.

About a month ago, half of our developers upgraded their local setups to run 1.4 and we read through the release notes to find which areas of our codebase needed changing. (As an aside, the Django community does an excellent job with the release note and we highly recommend you looking through them).

A few weeks later, we upgraded our continuous integration and staging servers. Naturally, we wanted to run 1.4 on hardware that mimics our production environment and found a few more issues.

The Tale

Here were the issues we ran into that may apply to others:

  • Django admin static media moved locations from django/contrib/admin/media/ to django/contrib/admin/static/admin/. If you rely on this location at all, you’ll need to change it.
  • Serialization changes to datetime and time. Django serializers have changed the output they return for datetimes and times to potentially include timezones, milliseconds, or a different format. If you have any sort of API that relies on the built-in JSON or XML serializers(note that Django REST framework does), you will need to take action to prevent your API users from experiencing potential issues.
  • The MySQL GIS backend used to have a bug that returned 1/0 for booleans instead of True/False (our @zmsmith reported it!). The bug got fixed so it could mean another potential change to any APIs you expose.
  • django.contrib.sitemaps bug fix with potential performance implications. Requests to sitemaps used to return cached responses by default. They no longer do. All of our sitemaps already utilized caching, but you it’s always good to double-check.
  • The content type for email encodings changed from quoted-printable to 8bit encodings with this commit. This caused some issues in our emails that we thankfully caught during testing.
  • Various modules/methods moved(django.conf.urls.defaults, django.contrib.auth.models.check_password, etc). The large majority of code that was moved around can still be imported from the old location, but it’s in your interest to upgrade the import paths now so that you don’t need to worry about it when the old import path becomes deprecated in version 1.5

The Wire and The Shut-Out

Bleeding EdgeAfter doing a full walk-through on our staging systems, we made the jump on production. Naturally, a few small bugs revealed themselves once our users stressed some edge cases. With our alert and monitoring systems, we were able to fix the few bugs we found within a few minutes of our rollout song stopping.

The Sting

This was our experience upgrading to 1.4. I hope you can now avoid running into some of these issues. If you have run into your own issues, please share them in the comments below.

Steve Pulec is a Developer at Yipit.