Django 2.0 - Is your project ready?
Django 2.0 is in beta now. It's expected to be released in December 2017. The question remains, is the rest of the world going to be ready?
Django has been on the 1.x branch for many years now. Upgrading to v2.0 would seem to be a big deal. But this coming release isn't necessarily a major change to the code base. Rather, it's a change to the way the Django maintainers handle versioning. They're changing to a sort-of semantic versioning system, where backwards-compatibility breaks only happen at the major version numbers.
When looking at the history of Django, there have been some major changes just within the 1.x branch:
Django 1.7 and South
This saw the switch from South database migrations (used in Django 1.6 and earlier) to the built-in migration system. Upgrading required removing all the previous South migrations, creating new "initial" migrations, and "faking" them to make sure the app could handle future schema changes. I've done this migration. On a system with dozens of apps and models, it could be difficult.
For third-party modules, this change was even harder. Most of them wanted to keep support for both Django 1.4 (the previous LTS release) and Django 1.7. This meant keeping parallel sets of migrations, one set for South and one for the new Django migration system.
This version, the current LTS version as of this writing, included some additional BC breaks. Some of the less actively maintained third-party packages still haven't caught up. The Mezzanine CMS, in particular, only supports up to Django 1.10 in its current stable release.
Along the way from Django 1.0 to 1.11, there have been frequent minor changes like requiring new syntax, or moving classes to a different namespace. These have required a bit of work with each upgrade, though generally it isn't too bad. Third-party modules have usually kept up pretty well.
So, what's the big deal with 2.0?
On first glance, the changes from Django 1.11 to 2.0 aren't much more difficult than the changes from 1.10 to 1.11. Except for one big one:
Django 2.0 requires Python 3.5 or higher.
Yes, you read that right. Django 1.11 is the last version to support Python 2.7. This might be a deal-breaker for some systems running older servers.
But, don't act surprised. Python 3.0 was released in 2008. In this developer's opinion, it's about time we all upgraded.
Tips for upgrading
Upgrading your project from one Django version to another isn't as daunting as you might think. Here's some tips that might help:
1. First, upgrade your project to the newest bugfix release (e.g., 1.8.x -> 1.8.18, or 1.11.x -> 1.11.7)
When the Django team locks in the changes that will be present in the next version, they go back and add compatibility and deprecation warnings to the previous minor versions. We'll rely on these warnings and notices in our next steps.
2. Go into your terminal and run
python -Wall manage.py check
This will catch some of the more common incompatibilities. Frequent changes for Django include making a keyword arggument required that used to be optional. (e.g., in Django 2.0, you need to provide an "on_delete" keyword for any models.ForeignKey properties. In 1.11 and earlier, this was optional and defaulted to
The -Wall option in the command above shows all warnings, and the warnings are what you're interested in. They let you see into the future a bit, by providing helpful hints about code that isn't compatible with the next Django version. If you see anything like "RemovedInDjango20Warning", that indicates places you need to refactor. In some cases, this will even tell you about code that isn't compatible with two Django versions in the future.
3. Upgrade third-party packages
If you're using any third-party packages like Django Rest Framework, django-celery, etc., you need to make sure they're compatible. The deprecation warnings above will help you find packages that need an upgrade. If possible, try to upgrade these before you upgrade Django itself.
Most regular Python packages (requests, regex, etc.) won't require any updates. They are naive about Django entirely.
If you're relying on a package that doesn't get much maintenance, find the project on GitHub or Bitbucket and check the issue queue. Someone might have already filed a bug report about the compatibility. You may need to fork a project and merge any compatibility fixes into your fork. Or, look for an alternate package. Maybe someone has done the upgrades for you and published it to PyPI under a different name.
Time to change your requirements.txt to use the new version of Django. Then run
If you're upgrading from an older version like 1.8.x, it's helpful to upgrade one minor release at a time. This lets you fix your code a little bit at a time. Get your project working on 1.9.x before trying 1.10.x, and so on.
5. Test it
Once the upgrade is installed, run
python -Wall manage.py check again to look for any more errors, and fix them.
Next, run your unit tests. These will hopefully catch any remaining incompatibilities. Fix the tests and get them all passing before you even try it in the browser.
Now, try it in the browser. You should have a working site! (Or, at least, close to it.)