{"id":2930,"library":"django-picklefield","title":"Pickled object field for Django","description":"django-picklefield provides an implementation of a pickled object field for Django models. It enables storing any picklable Python object directly in a database field, handling automatic serialization and deserialization. The library is currently at version 3.4.0 and maintains a healthy release cadence, with updates typically occurring at least once a year to support newer Django and Python versions.","status":"active","version":"3.4.0","language":"en","source_language":"en","source_url":"https://github.com/gintas/django-picklefield","tags":["django","field","pickle","serialization","orm"],"install":[{"cmd":"pip install django-picklefield","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core functionality is a custom Django model field. Version 3.4.0 supports Django 6.0.","package":"Django","optional":false}],"imports":[{"symbol":"PickledObjectField","correct":"from picklefield.fields import PickledObjectField"}],"quickstart":{"code":"import os\nfrom django.db import models\nfrom picklefield.fields import PickledObjectField\n\n# Configure Django for a minimal setup (usually done in settings.py)\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')\n# This is a dummy settings file for demonstration. In a real project,\n# ensure 'picklefield' is in INSTALLED_APPS.\n# A real settings.py would look something like:\n# INSTALLED_APPS = ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'picklefield', 'myapp']\n# DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}}\n# SECRET_KEY = 'insecure-dev-key'\n\nclass MyModel(models.Model):\n    data = PickledObjectField(compress=True)\n\n    def __str__(self):\n        return f\"MyModel with data: {self.data}\"\n\n# Example Usage (assuming Django setup is complete, e.g., via manage.py shell)\nif __name__ == '__main__':\n    # This part would typically be run within a Django shell or application context\n    # For a standalone runnable example, mocking Django ORM is complex.\n    # The following illustrates usage, but won't run directly without a full Django setup.\n    \n    # Create a dummy class to demonstrate pickling custom objects\n    class CustomObject:\n        def __init__(self, name, value):\n            self.name = name\n            self.value = value\n        def __repr__(self):\n            return f\"CustomObject(name='{self.name}', value={self.value})\"\n\n    print(\"To run this, ensure Django is configured and 'picklefield' is in INSTALLED_APPS.\")\n    print(\"Then run `python manage.py shell` and execute the following:\")\n    print(\"  from myapp.models import MyModel\")\n    print(\"  from myapp.quickstart import CustomObject\") # assuming this code is in myapp/quickstart.py\n    print(\"  obj = MyModel()\n  obj.data = {'list': [1, 2, {'a': 3}], 'custom': CustomObject('test', 123)}\n  obj.save()\n  retrieved_obj = MyModel.objects.first()\n  print(f'Stored data: {retrieved_obj.data}')\n  print(f'Type of retrieved data: {type(retrieved_obj.data)}')\n  print(f'Type of custom object: {type(retrieved_obj.data[\"custom\"])}')\")\n","lang":"python","description":"Define a model with `PickledObjectField` to store any picklable Python object. The `compress=True` argument can be used to enable zlib compression for larger objects. Data is automatically serialized upon saving and deserialized upon retrieval. The provided code demonstrates model definition and illustrates how to use the field to store complex data, including custom class instances."},"warnings":[{"fix":"NEVER store user-controllable data directly in a `PickledObjectField`. For user-provided data, use secure serialization formats like JSON, or ensure strict validation and sanitization. If `picklefield` is used for internal, trusted data, ensure no untrusted input can influence the stored objects.","message":"Storing untrusted or user-controlled data directly in `PickledObjectField` can lead to arbitrary code execution (insecure deserialization). The Python `pickle` module is inherently unsafe when handling data from untrusted sources. `django-picklefield` explicitly marks the field as `editable=False` to prevent declarative usage in Django forms and the admin, but direct assignment of unsanitized user input remains a critical risk.","severity":"breaking","affected_versions":"All versions"},{"fix":"After retrieving data with `values()` or `values_list()`, manually decode and unpickle the string. For example, using the internal `dbsafe_decode` function if accessed, or simply `pickle.loads(base64.b64decode(value))` if `compress=False` was used.","message":"Querying a `PickledObjectField` using `QuerySet.values()` or `QuerySet.values_list()` will return the raw, base64-encoded pickled string, not the deserialized Python object. You will need to manually decode and unpickle these values if you want the original Python objects.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If you need to store Django model instances, wrap them in a simple data structure like a list or tuple (e.g., `obj.data = [my_django_model_instance]`) before assigning them to the `PickledObjectField`.","message":"Directly storing instances of other Django models in a `PickledObjectField` can lead to issues due to how Django models manage their state and references, especially after model definition changes or during migrations.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always check the `django-picklefield` release notes or `pyproject.toml` for explicit Python and Django version compatibility before upgrading. Ensure your project's Python and Django versions meet the requirements of the `django-picklefield` version you intend to use.","message":"Major versions of `django-picklefield` have specific compatibility requirements for Python and Django versions. For instance, version 3.4.0 supports Django 6.0 and Python 3.10+ (including Python 3.14), but dropped support for Python 3.9. Version 3.3.0 dropped support for Django 3.2, 4.0, and 4.1.","severity":"breaking","affected_versions":"Prior to 3.4.0, or when upgrading across major versions."},{"fix":"Plan for backward compatibility when modifying classes stored in `PickledObjectField`. Consider versioning your pickled objects, implementing custom `__setstate__` and `__getstate__` methods, or providing migration logic for old object structures if breaking changes are necessary.","message":"If the class definition of an object stored in a `PickledObjectField` changes significantly after it has been pickled (e.g., attributes are removed, renamed, or types change), attempting to unpickle older data might result in `AttributeError`, `TypeError`, or other deserialization errors.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}