What's New in Django 3.1
Tags: django, python, tutorial
Published: 2020-07-08 19:37:36

Django 3.1 will be released in early August 2020 and comes with a number of major new features and many minor improvements including asynchronous views and middleware support, asynchronous tests, JSONField for all supported database backends (not just PostgreSQL), an updated admin page, `SECURE_REFERRER_POLICY`, and much more. The [official release notes](https://docs.djangoproject.com/en/3.1/releases/3.1/) are the canonical reference, but this post will cover some of the highlights as well as tips for upgrading.


## How to Upgrade
You really should strive to be on the latest version of both Django and Python. This will result in faster, more supported, and feature-laden code. To upgrade, create a new virtual environment, install Django 3.1, and run your test suite (you have one, yes?) by adding the `-Wa` flag to show full deprecation warnings. 

```
(env) $ python -Wa manage.py test
```

If you don't have tests in your project yet, you can still use `python -Wa manage.py runserver` to see some warnings. Refer to the [official upgrade list](https://docs.djangoproject.com/en/3.1/howto/upgrade-version/) for more advice. 

Django 3.1 requires Python 3.6, 3.7, or 3.8. You can read more about supported Python versions on the [Django prerequisites page](https://docs.djangoproject.com/en/3.1/faq/install/#what-python-version-can-i-use-with-django). If you're curious about Django's version and release policy, the [download page](https://www.djangoproject.com/download/) shows the supported versions timeline and future LTS (long-term support) releases.

For further context, the Django Chat podcast co-hosted by Django Fellow Carlton Gibson has episodes on [Django Versions](https://djangochat.com/episodes/django-versions) and [Django Security Releases](https://djangochat.com/episodes/security-releases).

## Asynchronous Views, Middleware, Tests
With version 3.0, Django began its async journey in earnest with [ASGI](https://asgi.readthedocs.io/en/latest/) support. In 3.1, Django now supports a fully asychronous request path with views, middleware, and tests/test client.

A basic example, provided in the docs, is to make a request that waits for half a second and then returns a response.

```python 
# views.py
async def my_view(request):
    await asyncio.sleep(0.5)
    return HttpResponse('Hello, async world!')
```

This works whether you are running WSGI or [ASGI](https://asgi.readthedocs.io/en/latest/) mode, which was first added in 3.0.

A more relevant example would be to asynchronously fetch a URL in Django using [HTTPX](https://www.python-httpx.org/), the next-generation version of the popular [requests](https://github.com/psf/requests) library.

## Cross-db JSONField
JSONField support for [models](https://docs.djangoproject.com/en/3.1/ref/models/fields/#django.db.models.JSONField) and [forms](https://docs.djangoproject.com/en/3.1/ref/forms/fields/#django.forms.JSONField) has now been extended to all Django-supported backends (MariaDB, MySQL, Oracle, and SQLite), not just PostgreSQL. This provides full support for [JSONField queries](https://docs.djangoproject.com/en/3.1/topics/db/queries/#querying-jsonfield).

```python
# models.py
from django.db import models 

class SoccerInfo(models.Model):
    data = models.JSONField()

SoccerInfo.objects.create(data={
    'team': 'Liverpool FC',
    'coaches': ['Klopp', 'Krawietz'],
    'players': {'forwards': ['Salah', 'Firmino', 'Mané']},
})
SoccerInfo.objects.filter(
    data__team='Liverpool',
    data__coaches__contains='Klopp',
    data__players__has_key='forwards',
).delete()
```

## Admin Layout
The admin now has a sidebar on the lefthand side for easier naviation on large screens. The historical breadcrumbs pattern is still available. If you'd like to disable the new sidebar, set [AdminSite.enable_nav_sidebar](https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.AdminSite.enable_nav_sidebar) to `False`.

Here is the older admin view:

![Django 3.0 Admin](https://dev-to-uploads.s3.amazonaws.com/i/wy4yqts1sqd69vo1y5ke.png)

And here is the new admin view with sidebar:

![Django 3.1 Admin](https://dev-to-uploads.s3.amazonaws.com/i/hv0wiobirpx7doap5pgw.png)

## pathlib 
Django has switched from using [os.path](https://docs.python.org/3.8/library/os.path.html) to the more modern and concise [pathlib](https://docs.python.org/3/library/pathlib.html). If you create a new project using the `startproject` command, the automatically generated `settings.py` file now defaults to `pathlib`.

Here is the Django 3.0 version:

```python
# settings.py
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}
```

And here is the newer Django 3.1 version:

```python
# settings.py
from pathlib import Path

BASE_DIR = Path(__file__).resolve(strict=True).parent.parent

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```

## SECURE_REFERRER_POLICY
The [SECURE_REFERRER_POLICY](https://docs.djangoproject.com/en/3.1/ref/settings/#std:setting-SECURE_REFERRER_POLICY) now defaults to 'same-origin', which is more secure. This is one of many steps the Django team makes around security. You can--and should--run the [Django deployment checklist](https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/) to ensure your project is secure before pushing to production: `python manage.py check --deploy`.


## Conclusion
There are many more new features, extensively documented in the [official release notes](https://docs.djangoproject.com/en/3.1/releases/3.1/), which are well-worth reading in full as well as the accompanying Django 3.1 documentation.

Every major new Django release is a team effort and 3.1 is no exception. The Django Fellows, [Carlton Gibson](https://twitter.com/carltongibson) and [Mariusz Feliask](https://twitter.com/MariuszFelisiak), are resonsible for an enormous amount of work to ensure the release process occurs smoothly and on time. Particular thanks are due to [Andrew Godwin](https://twitter.com/andrewgodwin?) for his work on async features and [Sage Abdullah](https://twitter.com/laymonage) for adding cross-db JSONFields.

If you'd like to support the continued development of Django, please do so on the [official fundraising page](https://www.djangoproject.com/fundraising/) or by becoming a [GitHub Sponsor](https://github.com/sponsors/django).