What Is New in Django 4.0
Django 4.0 brings a set of focused improvements that streamline form handling, enhance database capabilities, and modernize the template layer. The update also includes the usual deprecations to keep the framework moving forward.
| Category | Key Changes |
|---|---|
| New Features | scrypt password hasher, zoneinfo timezone support, functional unique constraints |
| Improvements | Redis cache backend, form rendering, template engine |
| Deprecations | PostgreSQL JSONField alias, url template tag |
How does Django 4.0 improve form handling?
Form rendering gets a major overhaul with the new div template structure. The old table-based rendering is now replaced by a more modern and accessible approach using <div> elements.
You can control this with the new form_template_name attribute and the FORM_RENDERER setting. In practice, this makes customizing form layouts with CSS significantly easier and cleaner.
What database enhancements should I know about?
The standout feature is the introduction of functional unique constraints. You can now create database-level constraints based on expressions, not just field values.
from django.db import models
from django.db.models import UniqueConstraint
from django.db.models.functions import Lower
class MyModel(models.Model):
name = models.CharField(max_length=100)
class Meta:
constraints = [
UniqueConstraint(
Lower('name'),
name='name_lower_uniq',
),
]
This is a powerful tool for ensuring data integrity directly within your database, like enforcing uniqueness on a case-insensitive email field.
Is the cache system getting any upgrades?
Yes, built-in support for Redis caching is now included. You can configure it using the new django.core.cache.backends.redis.RedisCache backend.
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
}
}
This official support simplifies setup for one of the most popular cache backends, removing the need for third-party packages.
What's new with security and passwords?
Django 4.0 adds the scrypt password hasher. It's a more modern and secure algorithm compared to PBKDF2, but it requires more memory to operate.
This matters because it provides a stronger defense against brute-force attacks. The new hasher will be the default in a future release, so it's good to start testing with it now.
Are there any important deprecations?
Two notable deprecations are the django.contrib.postgres.fields.JSONField and the old url template tag.
You should replace the PostgreSQL-specific JSONField with the new generic models.JSONField. Similarly, switch from {% url %} to the more explicit {% load url %} or use the new {% url ... as ... %} syntax.
FAQ
Is the new scrypt hasher the default now?
No, the PBKDF2 hasher remains the default for compatibility. The scrypt hasher is available as an option you can explicitly set in your PASSWORD_HASHERS list to start testing it.
Do I have to rewrite all my form templates?
No, the old table-based rendering is still available. You need to explicitly opt into the new div-based rendering by setting FORM_RENDERER = "django.forms.renderers.DivFormRenderer".
What happens if I don't replace the deprecated PostgreSQL JSONField?
It will continue to work in 4.0 but will raise warnings. It's scheduled for removal in a future version, so you should migrate to the generic models.JSONField.
Can I use Python's zoneinfo for time zones now?
Yes, Django 4.0 adds support for the zoneinfo module from the standard library. You can use it as an alternative to pytz by setting USE_DEPRECATED_PYTZ = False.
How do the new unique constraints work with migrations?
They are implemented as database-level constraints. When you create a UniqueConstraint with expressions like Lower('name'), Django will generate the appropriate SQL (e.g., CREATE UNIQUE INDEX ... ON ... (LOWER(name));) in your migration.