django-cryptography-django5
A fork of the original `django-cryptography` library, `django-cryptography-django5` provides primitives for easily encrypting data in Django models, wrapping the Python `cryptography` library. It offers field-level encryption for sensitive data, ensuring it's stored securely and decrypted automatically when accessed through Django. The library is actively maintained for Django 5 compatibility and is currently at version 2.2, with releases driven by Django version updates and bug fixes.
Common errors
-
django.core.exceptions.FieldError: Unsupported lookup 'exact' for EncryptedBigIntegerField or join on the field not permitted, perhaps you meant exact or iexact?
cause Attempting to apply `unique=True` or certain database lookups directly to an `encrypt()`-wrapped field, which stores varying ciphertext values for the same plaintext.fixRemove `unique=True` from the encrypted field definition. Implement uniqueness checks at the application level if required. Review queries against encrypted fields to ensure compatibility. -
ModuleNotFoundError: No module named 'django_cryptography'
cause The `django-cryptography-django5` package or its base (`django-cryptography`) is not installed in the current Python environment.fixInstall the package using pip: `pip install django-cryptography-django5`. -
ImportError: cannot import name 'encrypt' from 'django_cryptography.fields'
cause Incorrect import path or a version mismatch where `encrypt` might have been located elsewhere in older or different forks of the library.fixEnsure the correct import path `from django_cryptography.fields import encrypt` is used, and verify `django-cryptography-django5` is installed and up-to-date. -
DeprecationWarning: django.utils.baseconv is deprecated (when using Django 5.x)
cause Using the older, un-forked `django-cryptography` library with Django 5.x, which removed `django.utils.baseconv`.fixUpgrade to the `django-cryptography-django5` package, which provides explicit Django 5.x compatibility. Install with `pip install django-cryptography-django5`.
Warnings
- breaking The original `django-cryptography` library used `django.utils.baseconv`, which was removed in Django 5.x. Attempting to use the un-forked version with Django 5.x will result in import errors or deprecation warnings.
- gotcha Using `unique=True` on an encrypted model field (`encrypt(models.SomeField(unique=True))`) can lead to `FieldError: Unsupported lookup 'exact'` or cause the uniqueness constraint to be ignored by the database. Encryption changes the stored value, making true database-level uniqueness difficult to enforce on the ciphertext.
- gotcha The security of encrypted data critically depends on Django's `SECRET_KEY`. This key must be strong, unique to each deployment, and kept absolutely secret. Exposing it in version control or using a default/weak key compromises all encrypted data.
- gotcha The project's PyPI metadata indicates a 'Development Status :: 2 - Pre-Alpha'. While actively maintained, users should be aware of this classification, suggesting it may still be undergoing significant development or refinement.
Install
-
pip install django-cryptography-django5
Imports
- encrypt
from django_cryptography.fields import encrypt
Quickstart
import os
from django.db import models
from django_cryptography.fields import encrypt
# Ensure your Django settings.py has a strong SECRET_KEY and optionally ENCRYPTION_KEY
# For example, in settings.py:
# SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'your-very-long-and-random-secret-key-here')
# ENCRYPTION_KEY = os.environ.get('DJANGO_ENCRYPTION_KEY', SECRET_KEY) # Falls back to SECRET_KEY if not set
class SecureData(models.Model):
name = models.CharField(max_length=100)
# Encrypt the sensitive_info field
sensitive_info = encrypt(models.TextField())
def __str__(self):
return self.name
# Example usage (after running migrations):
# from myapp.models import SecureData
# data_entry = SecureData.objects.create(name='User A', sensitive_info='This is very secret data.')
# print(data_entry.sensitive_info) # Automatically decrypted when accessed via Django ORM