bgneal@4: Upgrading to Django 1.6 bgneal@4: ####################### bgneal@4: bgneal@4: :date: 2013-12-29 18:00 bgneal@4: :tags: Django bgneal@4: :slug: upgrading-to-django-1.6 bgneal@4: :author: Brian Neal bgneal@4: bgneal@4: Getting started bgneal@4: =============== bgneal@4: bgneal@4: `Django`_ 1.6 came out recently, which was soon followed by 1.6.1, and it looks bgneal@4: like 1.6.2 is on the way. I finally got around to upgrading two of my largest bgneal@4: sites. I thought I would make a list of what I changed at a high level for my bgneal@4: own reference. Perhaps someone else may find it useful as well. bgneal@4: bgneal@4: In any event, I highly recommend you read the excellent `release notes`_ and bgneal@4: `deprecation timeline`_. The changes in 1.6 didn't seem groundbreaking, but bgneal@4: they were numerous. I spent a lot of time reading through the notes and trying bgneal@4: to decide if the issues affected me or not. bgneal@4: bgneal@4: I recommend you run with warnings turned on:: bgneal@4: bgneal@4: $ python -Wall manage.py runserver bgneal@4: bgneal@4: This will help you flag down issues in your code. If you aren't sure where bgneal@4: a warning is coming from, you can turn warnings into exceptions and get bgneal@4: a traceback (see the Python docs on the warnings_ library). Another trick is to bgneal@4: put a pdb_ breakpoint in the Django code before or after the warning, then you bgneal@4: can examine the call stack with the ``w`` command. bgneal@4: bgneal@4: Upgrade Issues bgneal@4: ============== bgneal@4: bgneal@4: Here are the issues that I ran into. Of course you may have a very different bgneal@4: experience depending on what features of Django you used and the details of bgneal@4: your site. bgneal@4: bgneal@4: #. The location of the ``XViewMiddleware`` changed. I had to update my bgneal@4: ``MIDDLEWARE_CLASSES`` setting as a result. bgneal@4: #. Various ``get_query_set`` to ``get_queryset`` changes. The Django developers bgneal@4: have ironed out some naming inconsistencies in method names on both model bgneal@4: managers and ``ModelAdmin`` classes. bgneal@4: #. In template / form processing, the ``label_tag`` now includes the bgneal@4: ``label_suffix``. I noticed this when I saw that I had two colons on a form bgneal@4: field's label. bgneal@4: #. One very nice change that I am please to see is that Django now does test bgneal@4: discovery just like the unittest_ module in the standard library. To take bgneal@4: advantage of this I renamed all my test modules from ``view_tests.py`` to bgneal@4: ``test_views.py``, for example. This also let me get rid of ``import`` bgneal@4: statements in various ``__init__.py`` files in test subdirectories. In other bgneal@4: words, you no longer have to have silly lines like bgneal@4: ``from view_tests import *`` in your test packages' ``__init__.py`` files. bgneal@4: #. Django now supports database connection persistence. To take advantage of bgneal@4: this you need to set the CONN_MAX_AGE_ setting to a non-zero value. bgneal@4: #. The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting is now deprecated and can be bgneal@4: removed. For various reasons explained in the notes this never really worked bgneal@4: right anyway. bgneal@4: #. Updated to version 1.0 of the django-debug-toolbar_. The version I was using bgneal@4: would not work in Django 1.6. It is so good to see that this project is bgneal@4: being actively maintained again. There are several new panels and neat bgneal@4: features, check it out! bgneal@4: #. You now get a warning if you have a ``ModelForm`` without an ``exclude`` or bgneal@4: ``fields`` meta option. This is rather nice as I have been bit by this in bgneal@4: the past when a form suddenly started showing a newly added field that it bgneal@4: should not have. I added a ``fields`` option to a ``ModelForm`` as a result. bgneal@4: Unfortunately some third party applications I am using have this problem as bgneal@4: well. bgneal@4: #. The ``cycle`` tag has new XSS_ protection. To make use of it now, you have bgneal@4: to add a ``{% load cycle from future %}`` tag into your templates. bgneal@4: #. The ``django.contrib.auth`` password reset function is now using base 64 encoding of the bgneal@4: ``User`` primary key. The details are `here `_. This affected me bgneal@4: because I am using a custom password reset URL, and thus I needed to update bgneal@4: my URL pattern for both the new parameter name and the regular expression bgneal@4: for base 64. I missed this originally and I started getting 404's on my bgneal@4: password reset confirmation URLs. And yes, this is something I should have a bgneal@4: test for! bgneal@4: bgneal@4: What I didn't do bgneal@4: ================ bgneal@4: bgneal@4: Many of the warnings that I got came from third party modules that I have not bgneal@4: updated in a long time, including Celery_ and Haystack_. I am going to have to bgneal@4: schedule some time to update to the latest versions of these apps. Hopefully bgneal@4: the warnings will be fixed in the newer versions, but if not I can write bgneal@4: tickets or possibly submit patches / pull requests. This is the price of bgneal@4: progress I suppose. bgneal@4: bgneal@4: I also use a couple of smaller third party applications that seem to be no bgneal@4: longer maintained. These apps are now generating some warnings. I'll have to bgneal@4: fork them and fix these myself. Luckily these projects are on GitHub so this bgneal@4: should not be a problem. bgneal@4: bgneal@4: Finally I am still facing the problem of what to do about the deprecation of bgneal@4: the ``AUTH_PROFILE_MODULE`` and the ``get_profile`` method. This will be bgneal@4: removed in Django 1.7. I've been doing some more reading about this and I'm bgneal@4: less scared about this than I used to. I'll probably just change my profile bgneal@4: model to have a one-to-one relationship with the provided ``User`` model. I'll bgneal@4: have to do some more researching and thinking about this before Django 1.7. bgneal@4: bgneal@4: bgneal@4: Conclusion bgneal@4: ========== bgneal@4: bgneal@4: Once again the upgrade process went smoother and quicker than I thought thanks bgneal@4: to the excellent release notes and the Django team's use of Python warnings to bgneal@4: flag deprecated features. bgneal@4: bgneal@4: bgneal@4: .. _Django: https://www.djangoproject.com/ bgneal@4: .. _release notes: https://docs.djangoproject.com/en/1.6/releases/1.6/ bgneal@4: .. _deprecation timeline: https://docs.djangoproject.com/en/1.6/internals/deprecation/ bgneal@4: .. _warnings: http://docs.python.org/library/warnings.html bgneal@4: .. _pdb: http://docs.python.org/library/pdb.html bgneal@4: .. _unittest: http://docs.python.org/2/library/unittest.html bgneal@4: .. _CONN_MAX_AGE: https://docs.djangoproject.com/en/1.6/ref/settings/#conn-max-age bgneal@4: .. _XSS: http://en.wikipedia.org/wiki/Cross-site_scripting bgneal@4: .. _configurable user model: https://docs.djangoproject.com/en/1.5/topics/auth/customizing/#auth-custom-user bgneal@4: .. _django-debug-toolbar: https://pypi.python.org/pypi/django-debug-toolbar bgneal@4: .. _Celery: http://www.celeryproject.org/ bgneal@4: .. _Haystack: http://haystacksearch.org/