The much anticipated Django 2.0 was recently released and we are updating Pinax apps, client projects, and our own sites. This offers the perfect opportunity to share our process and some of the most common issues.

Saying Goodbye to Old Django

We recently wrote about our switch from TravisCI and Coveralls to CircleCI and CodeCov in How We Maintain High Levels of Code Quality.

In addition to adding Django 2.0 compatibility testing, we are dropping support for Django 1.8, 1.9, and 1.10 since their official support has ended. Python 3.3 has reached end of life and is removed from compatibility testing as well. Django 2.0 no longer supports Python 2, so that combination is also removed. This table shows the combinations of Django and Python supported by Pinax:

Django \ Python 2.7 3.4 3.5 3.6 1.11 * * * * 2.0 * * *

About Automated Testing

We run detox locally to see which test configurations fail and why. In addition, we use isort for automated import sorting and flake8-quotes for enforcing our double quote standard.

Django 2.0 Deprecations

These are the most common deprecations we encountered when upgrading to Django 2.0 as well as their resolutions.

from django.core.urlresolvers import include, url

Becomes:

from django.urls import include, url

2. MIDDLEWARE

In settings.py , we change MIDDLEWARE_CLASSES to MIDDLEWARE per the 1.11 docs.

Theh django.shortcuts.render_to_response() method is deprecated in favor of django.shortcuts.render() .

4. User.is_authenticated and User.is_anonymous

We change references to User.is_authenticated() and User.is_anonymous() to property references ( User.is_authenticated and User.is_anonymous ).

5. SessionAuthenticationMiddleware

We remove references to SessionAuthenticationMiddleware class.

This middleware is no longer needed since session authentication is unconditionally enabled in Django 1.10+.

6. assignment_tag becomes simple_tag

We change out @register.assignment_tag for @register.simple_tag .

These are the most common updates we made when upgrading to Django 2.0:

We add on_delete=models.CASCADE (or some other value) to all ForeignKey and OneToOne model fields. This is required for Django 2.0.

In reusuable apps that could be used for both 1.11 and 2.0 we create a compat.py module, if needed.

Currently the only import issue we know is mock which did not exist in Python standard library unittest until Python 3.3. See pinax-announcements 's compat.py for example imports, then use from .compat import mock .

9. URL namespacing

We need to add app_name = "pinax_announcements" or similar to urls.py .

For example:

from django.urls import url from . import views urlpatterns = [ url ( r " ^like/ ( ?P<content_type_id> \d + ) : ( ?P<object_id> \d + ) /$ " , views.LikeToggleView.as_view (), name = " like_toggle " ) ]

becomes:

from django.urls import url from . import views app_name = " pinax_likes " urlpatterns = [ url ( r " ^like/ ( ?P<content_type_id> \d + ) : ( ?P<object_id> \d + ) /$ " , views.LikeToggleView.as_view (), name = " like_toggle " ) ]

10. Use of path() in Projects

For new applications not requiring Django 1.11 compatibility we use path so we can write url definitions like this:

from django.urls import path from . import views app_name = " pinax_likes " urlpatterns = [ path ( " ^like/<int:content_type_id>:<int:object_id>/$ " , views.LikeToggleView.as_view (), name = " like_toggle " ) ]

Conclusion

There might be other issues to consider as you upgrade your site. These are just the ones we've hit upgrading apps and sites so far. For the full list of new features and changes in Django 2.0, see the official release notes.

If you need help, upgrading your site or building something new, don't hesitate to let us know.

Happy upgrading!