{"id":7170,"library":"django-encrypted-model-fields","title":"Django Encrypted Model Fields","description":"django-encrypted-model-fields provides a set of Django model fields that encrypt data before saving it to the database, leveraging the robust `cryptography` library. It's currently at version 0.6.5 and typically follows Django's release cycle for compatibility, with more frequent updates for bug fixes or features. It ensures data at rest is protected.","status":"active","version":"0.6.5","language":"python","source_language":"en","source_url":"https://github.com/JonathanStahl/django-encrypted-model-fields","tags":["django","encryption","security","models","fields","cryptography"],"install":[{"cmd":"pip install django-encrypted-model-fields","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core framework dependency, requires >=2.0","package":"Django","optional":false},{"reason":"Provides the underlying encryption primitives","package":"cryptography","optional":false}],"imports":[{"wrong":"from encrypted_model_fields.fields import EncryptedCharField","symbol":"EncryptedCharField","correct":"from encrypted_model_fields import EncryptedCharField"}],"quickstart":{"code":"import os\nfrom django.conf import settings\nfrom django.db import models\n\n# Minimal Django settings for standalone script testing\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        INSTALLED_APPS=[\n            'encrypted_model_fields' # Required for migrations/field registration\n        ],\n        DATABASES={\n            'default': {\n                'ENGINE': 'django.db.backends.sqlite3',\n                'NAME': ':memory:',\n            }\n        },\n        # CRUCIAL: Define encryption keys\n        ENCRYPTED_FIELD_KEYS={\n            'default': os.environ.get('ENCRYPTED_FIELD_DEFAULT_KEY', 'a_secret_key_for_dev_or_testing_ONLY_do_not_use_in_prod'),\n            'billing': os.environ.get('ENCRYPTED_FIELD_BILLING_KEY', 'another_key_for_billing_data')\n        },\n        # Required for any Django project\n        SECRET_KEY='django-insecure-testkey-very-insecure'\n    )\n\n# Ensure apps are loaded (needed for standalone scripts)\nimport django\ndjango.setup()\n\nfrom encrypted_model_fields.fields import EncryptedCharField, EncryptedTextField\n\nclass Customer(models.Model):\n    name = models.CharField(max_length=100)\n    email = EncryptedCharField(max_length=255)\n    notes = EncryptedTextField(blank=True, null=True, key_name='billing') # Use a specific key\n\n    def __str__(self):\n        return self.name\n\n# Example usage (requires database setup, e.g., via manage.py migrate)\nif __name__ == '__main__':\n    # This part would typically be in a Django shell or view\n    print(\"--- Quickstart Example ---\")\n\n    # In a real Django project, you'd run 'python manage.py makemigrations' and 'python manage.py migrate'\n    # For this standalone script, we'll simulate migrations for Customer model\n    from django.apps import apps\n    from django.core.management.commands import makemigrations, migrate\n    from io import StringIO\n\n    # Simulate makemigrations\n    # Note: This is a hack for a standalone script, not for production use.\n    # In a real project, 'encrypted_model_fields' would be in INSTALLED_APPS and 'python manage.py makemigrations/migrate' would be run.\n\n    # Create a simple fake app for the model\n    class FakeAppConfig(apps.AppConfig):\n        name = 'my_app'\n        verbose_name = 'My App'\n\n    apps.apps_ready = False # Reset app loading for standalone execution\n    apps.clear_cache()\n    apps.set_available_apps(['my_app'])\n    apps.populate(settings.INSTALLED_APPS + ['my_app'])\n    settings.INSTALLED_APPS += ['my_app']\n    apps.get_app_config('my_app').models = {'customer': Customer}\n\n    # For real migration, save models.py in an app and run commands.\n    # For this quickstart, we'll just interact with the model directly in memory after setup.\n\n    # Create a record\n    customer = Customer.objects.create(name='Alice', email='alice@example.com', notes='Confidential billing info.')\n    print(f\"Created customer: {customer.name}\")\n    print(f\"Stored email (encrypted): {customer.email}\") # Will show encrypted value if accessed directly before decrypt\n\n    # Retrieve and decrypt\n    retrieved_customer = Customer.objects.get(name='Alice')\n    print(f\"Retrieved email (decrypted): {retrieved_customer.email}\")\n    print(f\"Retrieved notes (decrypted): {retrieved_customer.notes}\")\n\n    # Update\n    retrieved_customer.email = 'alice.smith@example.com'\n    retrieved_customer.save()\n    print(f\"Updated email: {Customer.objects.get(name='Alice').email}\")","lang":"python","description":"This quickstart demonstrates defining a Django model with `EncryptedCharField` and `EncryptedTextField`. It highlights the critical `ENCRYPTED_FIELD_KEYS` setting in `settings.py`, which maps key names to their actual encryption keys. Data saved using these fields will be automatically encrypted and decrypted on access. Note the use of `os.environ.get` for secure key management. The standalone script includes a simplified Django setup for immediate execution (requires `Django` to be installed), but in a real project, you'd integrate the models into your existing Django application and manage migrations via `manage.py`."},"warnings":[{"fix":"Before upgrading, decrypt all data using the old version, upgrade the library, then re-encrypt all data using the new version. This is a manual process and requires careful planning and backup.","message":"Data encrypted with versions prior to 0.6.0 (which used `pycrypto`) is NOT readable by versions 0.6.0 and later (which use `cryptography`). An explicit data migration is required if upgrading from versions < 0.6.0 to >= 0.6.0.","severity":"breaking","affected_versions":"<0.6.0 to >=0.6.0"},{"fix":"Migrate your `settings.py` to use `ENCRYPTED_FIELD_KEYS` as a dictionary mapping key names to their string values. For example, `ENCRYPTED_FIELD_KEYS = {'default': 'your_default_key', 'some_other_key': 'another_key'}`.","message":"The `KEY_GENERATOR` and `KEY_STORE` settings were removed in version 0.6.0. They have been replaced by the `ENCRYPTED_FIELD_KEYS` dictionary setting.","severity":"breaking","affected_versions":"<0.6.0 to >=0.6.0"},{"fix":"Ensure `ENCRYPTED_FIELD_KEYS` is defined in `settings.py` as a dictionary, with at least a 'default' key if not using explicit `key_name` arguments on fields. For production, keys should be loaded from environment variables or a secure secret management system, NOT hardcoded.","message":"Failing to define `ENCRYPTED_FIELD_KEYS` in your Django `settings.py` or providing an invalid structure (e.g., not a dictionary or string) will lead to an `ImproperlyConfigured` exception or `MissingKeyError` when attempting to save or retrieve data.","severity":"gotcha","affected_versions":">=0.6.0"}],"env_vars":null,"search_vec":"'0.6.5':36 'bug':51 'compat':45 'cryptographi':29,67 'current':33 'cycl':43 'data':19,57 'databas':25 'django':1,6,14,40,62 'django-encrypted-model-field':5 'encrypt':2,7,18,63 'ensur':56 'featur':54 'field':4,9,16,66 'fix':52 'follow':39 'frequent':48 'leverag':26 'librari':30 'model':3,8,15,65 'protect':61 'provid':10 'releas':42 'rest':59 'robust':28 'save':21 'secur':64 'set':12 'typic':38 'updat':49 'version':35","created_at":"2026-04-16T13:46:29.522774+00:00","updated_at":"2026-04-16T13:46:29.522774+00:00","problems":{"verify_error":"Traceback (most recent call last):\n  File \"<string>\", line 1, in <module>\nImportError: cannot import name 'EncryptedCharField' from 'encrypted_model_fields' (/tmp/tmpcmc71ul5/venv/lib/python3.12/site-packages/encrypted_model_fields/__init__.py)"},"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.6.5","cli_name":"","cli_version":null,"type":"library","homepage":"https://gitlab.com/lansharkconsulting/django/django-encrypted-model-fields","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/django-encrypted-model-fields/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security","web-framework","database","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"import_fail","verified_at":"2026-07-03","last_verified":"2026-07-03","next_check":"2026-07-10","install_tag":null}}