Upcoming Django 6.0 Features
November 13, 2025The Django 6.0 release is scheduled for early next month. In this post, I wanted to briefly highlight the standout features.
1. Background Tasks
The upcoming Tasks API defines an interface for interacting with objects that are expected to run outside of the typical HTTP request/response cycle, like sending emails. The API includes a TaskResult class for obtaining task progress and return values.
Here’s what defining a simple task looks like:
import requests
from io import BytesIO
from django.tasks import task
@task(priority=5, queue_name="documents")
def process_document_for_user(user_id, document_url):
response = requests.get(document_url, timeout=10)
response.raise_for_status()
user = User.objects.get(id=user_id)
return expensive_processing(
user_id=user_id,
document_buffer=BytesIO(response.content)
)
You can obtain a TaskResult object by queueing the task:
result: TaskResult = process_document_for_user.enqueue(
user_id=user.id, document_url=my_doc_url
)
Assuming response.raise_for_status() throws an exception, then:
str(result.status) # "FAILED"
Otherwise, if the task completed without exception, the following would print the return value of expensive_processing:
if result.status is TaskResultStatus.SUCCESSFUL:
print(result.return_value)
Interestingly, Django deliberately avoids adding support for task runtimes; Django 6.0 defines a common API for queuing tasks and obtaining results, but does not prescribe how tasks should actually be executed. Instead, it allows future task execution providers to “plug in” via the familiar BACKEND setting.
Reading the Django Enhancement proposal (DEP 14), the main motivation for this is clear: "[…] the ecosystem is filled with incredibly popular frameworks, all of which interact with Django in slightly different ways […]"
It’s difficult to discuss this feature without celery coming to mind… It’s the de facto standard for defining and actually running tasks for Django projects, as far as I’m aware. I’ve used Celery extensively (it’s part of my go-to tooling for Django projects), and I’m curious to see how this standardized interface will be adopted by them, if at all.
I’d expect either the celery project itself or someone else to write a celery-compatible Task backend (or wrapper) in the near future, although a quick scan of the project’s issues page yields no results…
2. Template Partials
Built-in support for template partials is also coming in Django 6.0. I think this improvement to the core templates component is particularly welcome given the increasing adoption of htmx in Django projects, as shown in the recently published 2025 Django Developer Survey results.
Not to be confused with template inheritance or template inlining via include, template “partials” are intended for small HTML re-use via the new {% partialdef %} and {% partial %} tags.
Here’s a quick example:
{% partialdef user_card %}
<div class="card">
<h3>{{ user.username }}</h3>
<p>{{ user.email }}</p>
</div>
{% endpartialdef %}
<!-- Reuse the partial using the partial name and provide context -->
{% partial user_card user=current_user %}
The ability to directly access named partials is likely to become the best-practice approach when it comes to working with htmx-style “respond with an HTML snippet” requests.
This feature is essentially “vendoring-in” the django-template-partials third-party package.
Bonus: Content Security Policy
Django 6.0 also includes built-in Content Security Policy support. For a second time now, this is essentially “vendoring-in” a popular third-party package, in this case django-csp. I tend to view this pattern positively, as it further reinforces Django’s “batteries-included” philosophy.
“CSP” is a browser security standard that helps prevent cross-site scripting (XSS) and other code injection attacks by controlling which resources (scripts, images, etc.) can be loaded and executed on your web pages.
With Django 6.0, you can configure CSP policies directly in your settings:
from django.utils.csp import CSP
CONTENT_SECURITY_POLICY = {
"default-src": [CSP.SELF],
"script-src": [CSP.SELF, "cdn.example.com"],
"style-src": [CSP.SELF, CSP.UNSAFE_INLINE],
}
You’d also need to make sure to set up the proper middleware, see the how-to guide for more details.
Defining and maintaining a CSP is an important (and in my experience, often overlooked) part of a project’s production readiness. Setting up a proper CSP helps protect against injection attacks, which rank #5 in this year’s OWASP Top 10.
How to Use These Features Today
You can opt in to start testing these features today. The latest pre-release for the 6.0 branch is Django 6.0 beta 1, tagged as 6.0b1.
Install it using uv:
uv add "django==6.0b1"
or using pip:
pip install --pre django
Make sure to read through the deprecations and feature removals beforehand!
There are a bunch of other features and improvements coming besides the ones highlighted above, so be sure to check out the release docs if you’re interested.
Django 6.0 is set to be publicly released on December 3rd, 2025.