{"id":9662,"library":"django-bitfield","title":"Django Bitfield","description":"django-bitfield provides a `BitField` model field for Django, allowing developers to store multiple boolean flags efficiently in a single integer column in the database. It is currently at version 2.2.0, actively maintained, and follows Django's release cadence for compatibility.","status":"active","version":"2.2.0","language":"en","source_language":"en","source_url":"https://github.com/disqus/django-bitfield","tags":["django","database","flags","bitmask","models"],"install":[{"cmd":"pip install django-bitfield","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"The top-level package for models is 'bitfield', not 'django_bitfield'.","wrong":"from django_bitfield.models import BitField","symbol":"BitField","correct":"from bitfield.models import BitField"},{"note":"BitHandler is directly accessible from the 'bitfield' package root.","wrong":"from bitfield.models import BitHandler","symbol":"BitHandler","correct":"from bitfield import BitHandler"},{"symbol":"BitFieldFormField","correct":"from bitfield.forms import BitField as BitFieldFormField"}],"quickstart":{"code":"import os\nimport django\nfrom django.db import models\nfrom django.conf import settings\nfrom bitfield.models import BitField, BitHandler\n\n# Minimal Django settings for standalone use\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        DATABASES={\n            'default': {\n                'ENGINE': 'django.db.backends.sqlite3',\n                'NAME': ':memory:',\n            }\n        },\n        INSTALLED_APPS=[\n            'django.contrib.contenttypes',\n            'django.contrib.auth',\n            'bitfield'\n        ]\n    )\ndjango.setup()\n\nclass MyModel(models.Model):\n    # Define flags using a tuple of strings\n    flags = BitField(flags=(\n        'IS_ACTIVE',\n        'HAS_FEATURE_A',\n        'HAS_FEATURE_B',\n        'IS_ARCHIVED'\n    ))\n\n    class Meta:\n        app_label = 'myapp'\n\n# --- Example Usage ---\n\n# Create a new instance\nobj = MyModel.objects.create()\nprint(f\"Initial flags: {obj.flags.as_unique_int()}\") # Should be 0\n\n# Set a flag directly (returns True if set, False if already set)\nobj.flags.IS_ACTIVE = True\nobj.save()\nprint(f\"After setting IS_ACTIVE: {obj.flags.as_unique_int()} (IS_ACTIVE: {obj.flags.IS_ACTIVE})\")\n\n# Check a flag\nif obj.flags.HAS_FEATURE_A:\n    print(\"Has Feature A\")\nelse:\n    print(\"Does not have Feature A\")\n\n# Set multiple flags using BitHandler or integer value\n# Using BitHandler: manually set flags\nobj.flags = BitHandler(0, flags=('IS_ACTIVE', 'HAS_FEATURE_A', 'HAS_FEATURE_B', 'IS_ARCHIVED'))\nobj.flags.IS_ACTIVE = True\nobj.flags.HAS_FEATURE_B = True\nobj.save()\nprint(f\"After setting IS_ACTIVE and HAS_FEATURE_B: {obj.flags.as_unique_int()}\")\nprint(f\"IS_ACTIVE: {obj.flags.IS_ACTIVE}, HAS_FEATURE_A: {obj.flags.HAS_FEATURE_A}, HAS_FEATURE_B: {obj.flags.HAS_FEATURE_B}\")\n\n# Querying objects with specific flags\n# Get all objects where IS_ACTIVE is True\nactive_objects = MyModel.objects.filter(flags=MyModel.flags.IS_ACTIVE)\nprint(f\"Active objects count: {active_objects.count()}\")\n\n# Get all objects where IS_ACTIVE AND HAS_FEATURE_B are True\nactive_and_feature_b_objects = MyModel.objects.filter(flags__all=[MyModel.flags.IS_ACTIVE, MyModel.flags.HAS_FEATURE_B])\nprint(f\"Active and Feature B objects count: {active_and_feature_b_objects.count()}\")\n\n# Get all objects that have ANY of IS_ACTIVE or HAS_FEATURE_A (OR operation)\nactive_or_feature_a_objects = MyModel.objects.filter(flags__any=[MyModel.flags.IS_ACTIVE, MyModel.flags.HAS_FEATURE_A])\nprint(f\"Active or Feature A objects count: {active_or_feature_a_objects.count()}\")\n","lang":"python","description":"This quickstart demonstrates how to define a `BitField` on a Django model, set and check individual flags, and perform database queries based on flag states. It sets up minimal Django settings for a runnable example."},"warnings":[{"fix":"When upgrading from `1.x` to `2.x`, this change requires a specific data migration. If you have existing `BitField` columns, you must create a manual migration to alter the column type. Refer to the official documentation or release notes for guidance on schema migrations (e.g., using `django.db.connection.cursor().execute()` in a `RunPython` migration).","message":"Upgrade to `django-bitfield` 2.x changes the underlying database column type from `IntegerField` to `BigIntegerField`.","severity":"breaking","affected_versions":"2.0.0+"},{"fix":"Always interact with the `BitField` attribute via its `BitHandler` instance (e.g., `obj.flags.FLAG_NAME = True`) or explicitly create a `BitHandler` for complex assignments (e.g., `obj.flags = BitHandler(my_int_value, flags=obj.flags.get_flags())`).","message":"Assigning plain integers directly to a `BitField` will not automatically create a `BitHandler` and can lead to errors or unexpected behavior if not handled correctly.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For single flag checks, use `MyModel.objects.filter(flags=MyModel.flags.IS_ACTIVE)`. For multiple flags, use `flags__all` for AND (`flags__all=[MyModel.flags.FLAG_A, MyModel.flags.FLAG_B]`) or `flags__any` for OR (`flags__any=[MyModel.flags.FLAG_A, MyModel.flags.FLAG_B]`).","message":"When querying, ensure you use the `BitField` instance's flag constants for comparison (e.g., `MyModel.flags.IS_ACTIVE`), not just boolean `True`/`False` or integer values.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"The BitHandler is the value itself. Ensure you are assigning to a `BitField` model field, or if you need the integer representation, use `.as_unique_int()`.","cause":"Trying to assign a BitHandler directly to a non-BitField attribute or in a context that expects a raw integer.","error":"ValueError: Field 'flags' expected a number but got <BitHandler: IS_ACTIVE=True, HAS_FEATURE_A=False, ...>"},{"fix":"Run `python manage.py makemigrations` and `python manage.py migrate` after defining or altering your BitField model field. Verify `INSTALLED_APPS` includes the app containing the model.","cause":"The database schema has not been updated with the BitField column, or an incorrect app label is used.","error":"django.db.utils.OperationalError: no such column: myapp_mymodel.flags"},{"fix":"Remove the `default` argument. The default value for a `BitField` is implicitly 0 (no flags set). If you need specific flags set by default, you can override `save()` or use a post-save signal, or initialize with `BitHandler`.","cause":"BitField does not accept a 'default' argument in the same way as standard Django fields because its default state is an empty set of flags (integer 0).","error":"TypeError: BitField() got an unexpected keyword argument 'default'"}]}