Porting Django apps to Python 3

Django 1.5 now supports Python 3, so now’s the time to start thinking about porting your apps and sites. Come see how! I’ll talk about the porting techniques that work, and present two case studies: porting a site, and porting a reusable app.

by Jacob Kaplan-Moss

Do I want to use Python 3?

Python 3 has fewer warts

  • urllib / urllib2 replaced with urlparse
  • std library cleanup
  • funky syntax is killed
  • print() is a function!
  • super() syntax is better!
  • unicode no longer sucks!

Can I use Python 3?

A solid maybe. Missing pieces as of 3/16/2013:

  • No Python Image Library (PIL / Pillow)

  • No MySQL python 3 bindings aren’t that good.

  • Popular items on https://www.djangopackages.com:

    • No gunicorn as async (sync does work)
    • No django-debug-toolbar
    • No django-registration
    • No django-extensions
    • No Haystack
    • No django-tagging
    • No Sentry
    • No django-compressor
  • Much easier for new projects over existing sites


  1. Python 3 only

    • Brand new project
    • Fewer dependencies
  2. Translated source (2to3)

  3. Single codebase

3 only

Good for new Django sites.


First tool released for maintaining code, lets you translate from Python 2 to Python 3.

It’s amazing but not that practical: if you release the Python 3 version of code generated by 2to3 and then someone sends you a Python 3 patch, you have to port the patch to 2, apply it, and run 2to3.

Single (shared) source

Keep a single codebase that runs on both 2 and 3. Good for apps that need to support both.

How to port to Python 3

  • Choose an approach from the above.

  • Get the test suite running (use django-discover-runner, tox):

    envlist - py27-django14, py33-django15
  • Evaluate dependencies

  • syntax changes

    • print vs print()
    • django.utils.six
  • Fix unicode handling:


See Jeff Triplett’s port of django-sitetree


  • django.me/py3

Moving Forward

  • Django used to be the holdup for moving Python 3 usage forward
  • Q&A is at room 201 upstairs