What's New in Django 6.0 Major Features and Changes
Django 6.0 introduces a mix of big features and small but handy improvements. This release focuses on security, developer experience, and modern Python standards, making it easier than ever to build reliable apps.
Table of Contents
Article Details
- 3293 views
- Sep 20, 2025
- Category: Articles
- Topic: News and Updates
- Tags #django 6.0 #django features #django release notes #django updates #python web framework
Introduction: Django 6.0 Release
Django 6.0 is here with a mix of powerful new features and handy improvements. This release focuses on making applications more secure, faster to build, and easier to maintain. From Content Security Policy support to background tasks, Django continues to evolve with modern development needs while keeping its "batteries-included" promise.
For the full technical details, you can check the official Django 6.0 release notes .
Major New Features in Django 6.0
Django 6.0 introduces some exciting features that make building secure and modern web apps even smoother. Here are the highlights:
Content Security Policy (CSP) Support
Django now has built-in support for Content Security Policy headers, helping developers prevent XSS and data injection attacks ( docs reference ). Django now has built-in support for Content Security Policy headers, helping developers prevent cross-site scripting (XSS) and data injection attacks.
# settings.py
SECURE_CROSS_ORIGIN_OPENER_POLICY = "same-origin"
SECURE_CROSS_ORIGIN_EMBEDDER_POLICY = "require-corp"
Template Partials
Reuse common template blocks without repeating code using {% partial %}.
This makes your templates cleaner and more modular.
{% partial "components/navbar.html" %}
Built-in Background Tasks
Django 6.0 introduces simple background tasks without needing external tools like Celery. Great for lightweight async jobs.
from django.core.tasks import background
@background
def send_welcome_email(user_id):
# logic to send email in the background
pass
Modern Email API
Django now adopts Python's modern email.message.EmailMessage API,
making email handling more powerful and Pythonic.
from django.core.mail import EmailMessage
email = EmailMessage(
"Hello",
"This is a test email.",
"[email protected]",
["[email protected]"],
)
email.send()
Other Notable Improvements
Beyond the headline features, Django 6.0 ships a bunch of quality-of-life updates across admin, ORM, templates, emails, and more. Here are the small-but-mighty changes you'll actually feel in day-to-day work.
Admin
- Admin icons updated to Font Awesome Free 6.7+ for a cleaner, consistent UI.
- Customize the password change form via
AdminSite.password_change_form.
Example - custom password change form
# admin.py
from django.contrib import admin
from .forms import MyPasswordChangeForm
class MyAdminSite(admin.AdminSite):
password_change_form = MyPasswordChangeForm
Auth
- PBKDF2 hasher iterations increased for stronger defaults (security hardening).
PostgreSQL & DB Features
Lexemeexpression for full-text search - safer term handling and easy boolean ops.StringAggpromoted to a general aggregate, not Postgres-only anymore.AnyValueaggregate returns an arbitrary non-null value - handy in GROUP BY queries.Aggregate(order_by=...)for ordered aggregation results.
Examples
# Postgres FTS: combine terms with & and | using Lexeme
from django.contrib.postgres.search import SearchQuery, Lexeme
from blog.models import Post
query = SearchQuery(Lexeme("django") & ~Lexeme("flask") | Lexeme("htmx", prefix=True))
qs = Post.objects.filter(search_vector=query)
# Ordered aggregation: top tags as a comma-separated string
from django.db.models import Aggregate, StringAgg
from blog.models import Tag
Tag.objects.values("category").annotate(
tag_list=StringAgg("name", delimiter=", ", order_by=("name",))
)
Models & ORM
Constraints.check()integrates with Django's checks framework.QuerySet.raw()works withCompositePrimaryKeymodels.- Subqueries returning composite keys allowed in more lookups (not just
__in). GeneratedFieldand expression-assigned fields refresh aftersave()on backends withRETURNING.
Pagination (Async)
- New
AsyncPaginatorandAsyncPagefor async views and APIs.
# views.py - example async pagination
from django.core.paginator import AsyncPaginator
from django.http import JsonResponse
from .models import Article
async def articles_api(request):
page_num = int(request.GET.get("page", 1))
paginator = AsyncPaginator(Article.objects.all(), 20)
page = await paginator.get_page(page_num)
return JsonResponse({
"count": paginator.count,
"num_pages": paginator.num_pages,
"items": [a.title for a in page.object_list],
})
Templates
forloop.lengthavailable inside{% for %}loops.querystringtag always prefixes with?and now accepts multiple mapping args.
{# Example: show position out of total using forloop.length #}
{% for obj in objects %}
<li>{{ forloop.counter }} / {{ forloop.length }} - {{ obj.name }}</li>
{% endfor %}
{# Example: merge query params #}
<a href="{% url 'articles:list' %}{% querystring request.GET {'page': 2} {'tag': 'django'} %}">
Next page
</a>
Requests & Responses
- Multiple
Cookieheaders supported for HTTP/2 on ASGI servers.
EmailMessage.message(policy=...)accepts an explicit email policy.EmailMessage.attach()can take a modernMIMEPartobject.
from email.mime.text import MIMEText
from email.policy import default
from django.core.mail import EmailMessage
msg = EmailMessage("Hi", "Body", "[email protected]", ["[email protected]"])
msg.message(policy=default) # use modern policy
msg.attach(MIMEText("Extra text part", "plain"))
msg.send()
Testing
DiscoverRunnersupports parallel tests with theforkserverstart method.
Sources: Django 6.0 release notes and dev docs. See sections on minor features, templates, ORM, pagination, email, and testing.
Deprecations & Cleanups
Django 6.0 also removes some older paths and marks certain APIs as deprecated. These aren't show-stoppers but are important for developers to keep in mind as they plan ahead for future upgrades.
Mail API Updates
- Positional arguments in
EmailMessage.attach()are deprecated - use keyword arguments instead. - Several older
django.core.mailfunctions are moving towards the new Python email standards.
# Old style (deprecated)
email.attach("file.txt", "content", "text/plain")
# Recommended style
email.attach(
filename="file.txt",
content="content",
mimetype="text/plain"
)
Database & ORM
- Certain internal ORM expression parameters now require keyword arguments.
- Older database backends or versions (like MariaDB 10.5) are no longer supported.
Miscellaneous
- Functions and classes previously marked as deprecated in earlier releases have now been fully removed.
- Cleanups across admin, templates, and contrib apps for consistency with modern Django practices.
Sources: Django 6.0 release notes - see sections on deprecations, mail API updates, ORM parameter changes, and removed features.
Conclusion
Django 6.0 proves once again why it's one of the most reliable frameworks for modern web development. Here are the main takeaways from this release:
- Security first: Built-in Content Security Policy support makes apps safer out of the box.
- Cleaner templates: Template Partials let you reuse UI elements without duplication.
- Simpler background work: Native background tasks reduce the need for extra tools in lightweight projects.
- Modern email handling: Integration with Python's new email API means better flexibility and standards compliance.
- Polish all around: Improvements in admin, ORM, templates, and testing make daily development smoother.
In short, Django 6.0 is a forward-looking release that keeps the framework modern, secure, and developer-friendly. Use LTS for stability, or jump into 6.0 for innovation.
👉 If you're looking for stability and a step-by-step learning path, check out our complete Django 5.2 Tutorial Series - perfect for beginners and production projects.