I started porting Django to Python 3 at PyCon2008. The current patch allows me to get through the tutorial, but there are certainly large parts of the code base that I haven't touched, so more issues are likely to show up.

The current version of the patch is available on http://bitbucket.org/loewis/django-3k/

Note: an update of the port, which features a single codebase for 2.x and 3.x, and which passes the regression tests on Python 2.5, 2.6, 2.7 and 3.2, is available at https://bitbucket.org/vinay.sajip/django/ (default branch).

For general tips on porting to Python 3, see PortingPythonToPy3k (ideally, much of the non-Django-specific information from the porting Django page should be included on the general porting page).

Porting Strategy

This port attempts to maintain compatibility with older Python versions from a single code base; the goal is to support all versions that Django supports, plus 3.1.

To simplify porting, and to allow running Django from a single code base, I changed distutils to allow invocation of the 2to3 tool as part of the build_py step, if setup.py is invoked from python3.0. To add that support, I first made 2to3 a standard library (named lib2to3).

This approach mostly works, and has the following flaws:


The changes can be roughly grouped into the following categories

Naming Changes

A number of modules that django uses have been removed, or renamed:

In addition, a few functions and attributes got renamed:

Bytes vs. Strings

Python 3 separates byte strings and character strings clearly, and defines that string literals are character strings, unless prefixed as bytes. Character strings are always represented as sequence of Unicode characters.

2to3 will change all occurrences of the unicode identifier to str, but leave all occurrences of str alone. It will also change all Unicode string literals to regular string literals, but leave the existing string literals alone.

As a consequence, it produces code like this one:

  class EscapeString(str, EscapeData): pass
  class EscapeUnicode(str, EscapeDate): pass

These types were meant to be separate, but became identical after 2to3.

To fix these problems, I made the following changes:

New-style classes

Other changes

Open Issues


Python 3k. Python 3.0. Python 3000. Py3K. Django.

PortingDjangoTo3k (last edited 2011-12-04 16:22:40 by VinaySajip)

Unable to edit the page? See the FrontPage for instructions.