Overview
Django 1.8, released on April 1, 2015, introduces support for multiple template engines within a single project. It is now possible to use Jinja2 alongside or instead of Django's native template engine. This release also brings new Query Expressions and enhanced security middleware.
Key Features
Multiple template engine support
The TEMPLATES setting replaces the older template settings and allows configuring one or more engines. Each engine can have its own template directories and specific options.
# settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['templates/django'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
],
},
},
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': ['templates/jinja2'],
'OPTIONS': {
'environment': 'myproject.jinja2.environment',
},
},
]
Query Expressions
The new Query Expressions allow performing calculations directly in the database with F(), Value(), Func(), and Case/When objects. These expressions are composable and avoid fetching data into Python to perform calculations.
from django.db.models import F, Value, Case, When, CharField
# Database update without loading objects into Python
Product.objects.filter(on_sale=True).update(
price=F('price') * 0.9 # 10% discount
)
# Conditional expression with Case/When
orders = Order.objects.annotate(
status_label=Case(
When(status='P', then=Value('Pending')),
When(status='S', then=Value('Shipped')),
When(status='D', then=Value('Delivered')),
default=Value('Unknown'),
output_field=CharField(),
)
)
