A drop-in replacement for django-hashid-field with Django 5.x/6.x support
Project description
shopcloud-django-hashid
A drop-in replacement for django-hashid-field with Django 5.x and 6.x support.
Features
- Drop-in compatible: Same import paths and API as
django-hashid-field - Django 5.x/6.x support: Designed for modern Django versions
- Zero migration effort: Existing migrations work without changes
- Identical hashid output: Same salt produces same hashids
- Full ORM support: Works with all Django ORM operations
- Django REST Framework integration: Automatic serialization support
- Thread-safe: Safe for concurrent use in production
Installation
pip install shopcloud-django-hashid
Migration from django-hashid-field
pip uninstall django-hashid-field
pip install shopcloud-django-hashid
No code changes required. Your existing imports continue to work:
from hashid_field import HashidField, HashidAutoField
from hashid_field import BigHashidField, BigHashidAutoField
from hashid_field import Hashid
Verify no migrations are needed:
python manage.py makemigrations --dry-run
# Should output: "No changes detected"
Quick Start
Model Definition
from django.db import models
from hashid_field import HashidAutoField, HashidField
class Article(models.Model):
id = HashidAutoField(primary_key=True)
title = models.CharField(max_length=200)
class Comment(models.Model):
id = HashidAutoField(primary_key=True)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
reference_code = HashidField() # Non-primary key hashid
Django Settings
# settings.py
# Required: Set your salt (keep secret!)
HASHID_FIELD_SALT = "your-secret-salt-here"
# Optional: Customize defaults
HASHID_FIELD_MIN_LENGTH = 7
HASHID_FIELD_ALLOW_INT_LOOKUP = False
Usage
# Create
article = Article.objects.create(title="Hello World")
print(article.id) # Hashid('kRm4x7')
print(str(article.id)) # 'kRm4x7'
print(int(article.id)) # 1
# Query by hashid string
article = Article.objects.get(pk='kRm4x7')
Field Types
| Field | Base | Use Case |
|---|---|---|
HashidField |
IntegerField |
General hashid storage |
BigHashidField |
BigIntegerField |
Large integer hashids |
HashidAutoField |
AutoField |
Primary key with hashid |
BigHashidAutoField |
BigAutoField |
Big auto primary key |
Settings
| Setting | Default | Description |
|---|---|---|
HASHID_FIELD_SALT |
"" |
Global salt for encoding |
HASHID_FIELD_MIN_LENGTH |
7 |
Minimum hashid length |
HASHID_FIELD_ALLOW_INT_LOOKUP |
False |
Allow integer-based queries |
HASHID_FIELD_ENABLE_HASHID_OBJECT |
True |
Return Hashid objects vs strings |
Django REST Framework
If DRF is installed, HashidFields serialize automatically:
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title']
# id will serialize as hashid string, e.g., "kRm4x7"
Performance
- Fast encoding and decoding, suitable for production use
- Thread-safe: Yes, suitable for production environments
Best Practices
-
Set salt in production:
# settings.py HASHID_FIELD_SALT = os.environ.get("HASHID_SALT", "your-secret-salt")
-
Custom salts for sensitive fields:
class Order(models.Model): id = HashidAutoField(primary_key=True, salt="order-specific-salt")
-
Hashids are deterministic: Same salt + same ID = same hashid
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| "Invalid hashid" Error | Inconsistent salt | Set same salt in all environments |
| Performance issues | N+1 Queries | Use select_related and prefetch_related to eager-load related objects |
| Hashid changes | Salt changed | Never change salt in production |
Settings Reference (Complete)
| Setting | Default | Description |
|---|---|---|
HASHID_FIELD_SALT |
"" |
Global salt for all fields |
HASHID_FIELD_MIN_LENGTH |
7 |
Minimum hashid length |
HASHID_FIELD_ALPHABET |
hashids library default |
Allowed characters |
HASHID_FIELD_LOOKUP_EXCEPTION |
False |
Raise exception on invalid lookups |
HASHID_FIELD_ALLOW_INT_LOOKUP |
False |
Allow integer-based queries |
HASHID_FIELD_ENABLE_HASHID_OBJECT |
True |
Return Hashid objects vs strings |
Requirements
- Python 3.12+
- Django 5.0+
- hashids >= 1.3.1
Publishing to PyPI (Maintainers)
This package uses PyPI Trusted Publishing for secure, token-free releases:
-
Configure Trusted Publisher on PyPI:
- Log in to pypi.org
- Go to your account → Publishing → Add a new trusted publisher
- Set repository owner, name, and workflow file (
publish.yml)
-
Create a Release:
- Update version in
pyproject.tomlandhashid_field/__init__.py - Update
CHANGELOG.md - Create a GitHub Release with a tag (e.g.,
v0.1.0) - The GitHub Action will automatically publish to PyPI
- Update version in
License
MIT License - see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shopcloud_django_hashid-0.8.0.tar.gz.
File metadata
- Download URL: shopcloud_django_hashid-0.8.0.tar.gz
- Upload date:
- Size: 38.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f49ff2fcd252699b277a28fb4cab227823e1b1f62025282f7a98e8f3e656082
|
|
| MD5 |
9e6fed71a1f6fb133e2f2f0623212f6d
|
|
| BLAKE2b-256 |
bb97e3f01b18a16540f76929c7b41037ab645875f0930fbdea066f934ad045d7
|
Provenance
The following attestation bundles were made for shopcloud_django_hashid-0.8.0.tar.gz:
Publisher:
publish.yml on Talk-Point/shopcloud-django-hashid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shopcloud_django_hashid-0.8.0.tar.gz -
Subject digest:
2f49ff2fcd252699b277a28fb4cab227823e1b1f62025282f7a98e8f3e656082 - Sigstore transparency entry: 1342556105
- Sigstore integration time:
-
Permalink:
Talk-Point/shopcloud-django-hashid@b4a15c8ca56f673bb5e89eea2c8151fd6e071231 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/Talk-Point
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b4a15c8ca56f673bb5e89eea2c8151fd6e071231 -
Trigger Event:
push
-
Statement type:
File details
Details for the file shopcloud_django_hashid-0.8.0-py3-none-any.whl.
File metadata
- Download URL: shopcloud_django_hashid-0.8.0-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb9b3e61036611cff04ebe3026d84e563a5eaf27110ea27adc7a31a5292dfaa8
|
|
| MD5 |
d4840a1e1e9881cc4f38e38fde0afcab
|
|
| BLAKE2b-256 |
2d41b8a98dffd93f9dff25b41660cd8fec35cd0038e7799915a2e335c0c12eec
|
Provenance
The following attestation bundles were made for shopcloud_django_hashid-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on Talk-Point/shopcloud-django-hashid
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shopcloud_django_hashid-0.8.0-py3-none-any.whl -
Subject digest:
cb9b3e61036611cff04ebe3026d84e563a5eaf27110ea27adc7a31a5292dfaa8 - Sigstore transparency entry: 1342556113
- Sigstore integration time:
-
Permalink:
Talk-Point/shopcloud-django-hashid@b4a15c8ca56f673bb5e89eea2c8151fd6e071231 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/Talk-Point
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b4a15c8ca56f673bb5e89eea2c8151fd6e071231 -
Trigger Event:
push
-
Statement type: