Django Hashid Field

3.4.1 · active · verified Thu Apr 16

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.

Common errors

Warnings

Install

Imports

Quickstart

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`.

import os
from django.db import models
from django.conf import settings
from hashid_field import HashidField, HashidAutoField

# Minimal Django settings for the field to work
if not settings.configured:
    settings.configure(
        DEBUG=True,
        SECRET_KEY='a-very-secret-key',
        INSTALLED_APPS=['django_hashid_field_test'],
        DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
        HASHID_FIELD_SALT=os.environ.get('DJANGO_HASHID_FIELD_SALT', 'default-test-salt'),
        HASHID_FIELD_ALLOW_INT_LOOKUP=True
    )

class Product(models.Model):
    # Use HashidAutoField for a primary key (replaces integer ID)
    id = HashidAutoField(primary_key=True)
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    # Use HashidField for a non-primary key field
    # It stores an integer in the DB, but exposes a hashid string
    legacy_id = HashidField(null=True, blank=True)

    def __str__(self):
        return f"{self.name} ({self.id})"

# Example usage (after makemigrations and migrate)
# from django.db import connection
# from django.apps import apps
# apps.populate(settings.INSTALLED_APPS)
# with connection.schema_editor() as schema_editor:
#     schema_editor.create_model(Product)
#
# product = Product.objects.create(name="Test Product", price=99.99, legacy_id=12345)
# print(f"Created Product: {product.name}, Hashid ID: {product.id}, Legacy Hashid: {product.legacy_id}")
# 
# # Look up by hashid string
# retrieved_product = Product.objects.get(id=product.id)
# print(f"Retrieved Product by hashid: {retrieved_product.name}")
#
# # Look up by underlying integer ID (if HASHID_FIELD_ALLOW_INT_LOOKUP is True)
# retrieved_product_int = Product.objects.get(id=product.id.id)
# print(f"Retrieved Product by int ID: {retrieved_product_int.name}")

view raw JSON →