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.
django.urls
1. from django.core.urlresolvers import include, url
Becomes:
from django.urls import include, url
MIDDLEWARE
2. In settings.py
, we change MIDDLEWARE_CLASSES
to MIDDLEWARE
per the 1.11 docs.
django.shortcuts.render()
3. Theh django.shortcuts.render_to_response()
method is deprecated in favor of django.shortcuts.render()
.
User.is_authenticated
and User.is_anonymous
4. 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+.
assignment_tag
becomes simple_tag
6. We change out @register.assignment_tag
for @register.simple_tag
.
Django 2.0 Updates
These are the most common updates we made when upgrading to Django 2.0:
on_delete=models.CASCADE
7. We add on_delete=models.CASCADE
(or some other value) to all ForeignKey
and OneToOne
model fields. This is required for Django 2.0.
compat.py
8. 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")
]
path()
in Projects
10. Use of 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!