{"id":8949,"library":"django-hashid-field","title":"Django Hashid Field","description":"django-hashid-field is a Django library that provides model fields for obfuscating database primary keys using Hashids. It converts integer IDs into short, unique, non-sequential string identifiers, enhancing data privacy and preventing enumeration attacks. The current version is 3.4.1 and it generally follows a release cadence tied to Django LTS releases and feature enhancements.","status":"active","version":"3.4.1","language":"en","source_language":"en","source_url":"https://github.com/nshafer/django-hashid-field","tags":["Django","hashids","model fields","ID obfuscation","primary key"],"install":[{"cmd":"pip install django-hashid-field","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core dependency for generating and decoding hashids.","package":"hashids","optional":false},{"reason":"Framework dependency for a Django model field.","package":"Django","optional":false}],"imports":[{"symbol":"HashidField","correct":"from hashid_field import HashidField"},{"note":"HashidPrimaryKey was renamed to HashidAutoField in v2.0.0.","wrong":"from hashid_field import HashidPrimaryKey","symbol":"HashidAutoField","correct":"from hashid_field import HashidAutoField"},{"symbol":"HashidBigAutoField","correct":"from hashid_field import HashidBigAutoField"}],"quickstart":{"code":"import os\nfrom django.db import models\nfrom django.conf import settings\nfrom hashid_field import HashidField, HashidAutoField\n\n# Minimal Django settings for the field to work\nif not settings.configured:\n    settings.configure(\n        DEBUG=True,\n        SECRET_KEY='a-very-secret-key',\n        INSTALLED_APPS=['django_hashid_field_test'],\n        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},\n        HASHID_FIELD_SALT=os.environ.get('DJANGO_HASHID_FIELD_SALT', 'default-test-salt'),\n        HASHID_FIELD_ALLOW_INT_LOOKUP=True\n    )\n\nclass Product(models.Model):\n    # Use HashidAutoField for a primary key (replaces integer ID)\n    id = HashidAutoField(primary_key=True)\n    name = models.CharField(max_length=255)\n    price = models.DecimalField(max_digits=10, decimal_places=2)\n\n    # Use HashidField for a non-primary key field\n    # It stores an integer in the DB, but exposes a hashid string\n    legacy_id = HashidField(null=True, blank=True)\n\n    def __str__(self):\n        return f\"{self.name} ({self.id})\"\n\n# Example usage (after makemigrations and migrate)\n# from django.db import connection\n# from django.apps import apps\n# apps.populate(settings.INSTALLED_APPS)\n# with connection.schema_editor() as schema_editor:\n#     schema_editor.create_model(Product)\n#\n# product = Product.objects.create(name=\"Test Product\", price=99.99, legacy_id=12345)\n# print(f\"Created Product: {product.name}, Hashid ID: {product.id}, Legacy Hashid: {product.legacy_id}\")\n# \n# # Look up by hashid string\n# retrieved_product = Product.objects.get(id=product.id)\n# print(f\"Retrieved Product by hashid: {retrieved_product.name}\")\n#\n# # Look up by underlying integer ID (if HASHID_FIELD_ALLOW_INT_LOOKUP is True)\n# retrieved_product_int = Product.objects.get(id=product.id.id)\n# print(f\"Retrieved Product by int ID: {retrieved_product_int.name}\")\n","lang":"python","description":"This example demonstrates how to define models using `HashidAutoField` for primary keys and `HashidField` for other fields. It also highlights the required `HASHID_FIELD_SALT` setting and how to enable integer lookups with `HASHID_FIELD_ALLOW_INT_LOOKUP`."},"warnings":[{"fix":"Upgrade Django to 3.2+ and Python to 3.8+. For REST Framework integration, install and use `django-hashid-rest-framework`.","message":"Version 3.0.0 dropped support for older Django (< 3.2) and Python (< 3.8) versions. The `hashid_field.rest` module was removed and moved to a separate library, `django-hashid-rest-framework`.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Update `HashidPrimaryKey` to `HashidAutoField` in your models. If you need to maintain compatibility with existing hashids, explicitly configure `HASHID_FIELD_SALT` and `HASHID_FIELD_ALPHABET` in your Django settings to match your previous setup.","message":"Version 2.0.0 renamed `HashidPrimaryKey` to `HashidAutoField`. It also changed default `salt` and `alphabet` settings, which could result in different hashids being generated for the same integer IDs if you are upgrading and relied on previous defaults.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Add a unique, secret string to your Django `settings.py`, e.g., `HASHID_FIELD_SALT = 'your-super-secret-salt-here'`.","message":"The `HASHID_FIELD_SALT` setting is mandatory. The library will raise an `ImproperlyConfigured` exception if it is not set in your Django settings.","severity":"gotcha","affected_versions":"All"},{"fix":"To enable integer lookups (e.g., `MyModel.objects.get(id=123)`), set `HASHID_FIELD_ALLOW_INT_LOOKUP = True` in your Django settings. Otherwise, always query using the hashid string (e.g., `MyModel.objects.get(pk='abCdef')`).","message":"By default, querying objects directly by their underlying integer ID is disabled when using `HashidAutoField` or `HashidField` for primary keys. Attempts to do so will result in a `TypeError` or `ValueError`.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Add `HASHID_FIELD_SALT = 'your-unique-secret-salt'` to your `settings.py`.","cause":"The required `HASHID_FIELD_SALT` setting is missing from your Django project's `settings.py`.","error":"django.core.exceptions.ImproperlyConfigured: HASHID_FIELD_SALT must be set in settings.py"},{"fix":"To query by hashid, use the appropriate field lookup: `MyModel.objects.get(pk='abCdef')` for primary keys, or `MyModel.objects.get(hashid_field_name='abCdef')` for non-primary key `HashidField`s. Alternatively, set `HASHID_FIELD_ALLOW_INT_LOOKUP = True` in `settings.py` to allow both integer and hashid lookups.","cause":"Attempting to query a `HashidAutoField` or `HashidField` using its hashid string when `HASHID_FIELD_ALLOW_INT_LOOKUP` is `False`.","error":"TypeError: Field 'id' expected a number but got 'abCdef'"},{"fix":"Replace `HashidPrimaryKey` with `HashidAutoField`. Update your imports to `from hashid_field import HashidAutoField`.","cause":"You are trying to import or use the old field name `HashidPrimaryKey` which was renamed in version 2.0.0.","error":"AttributeError: module 'hashid_field' has no attribute 'HashidPrimaryKey'"}]}