Skip to main content

django-niceid

IDs look like user_1KGGWGM8FEABRJA533GJKYW0B in Python and APIs, while PostgreSQL stores them as native UUID values (sortable, compact, index-friendly).

Why

  • Ordering: Natural ordering behavior just like integer auto-increment IDs.
  • Global Uniqueness: Unlike auto-incredemt IDs.
  • Clarity: Keep globally unique IDs while still having human-recognizable prefixes like user_ or org_.
  • Efficiency: Store IDs as native UUID in PostgreSQL instead of strings.
  • Performance: Better index locality than random UUIDv4 by using time-ordered UUIDv7.
  • Consistency: Standardize ID parsing/validation across Django models, routes, forms, and serializers.
  • Friendly: Crockford base32 keeps IDs compact and human-friendly in URLs and APIs. No 0 v O or I v L, only upper-case. Easy to dictate and read from logs, screenshots, errors.

Requirements

  • Python 3.14+ (uuid.uuid7 in the standard library)
  • Django 5.1+
  • PostgreSQL 18+ with native UUID support and a built-in uuidv7() function

Install

pip install django-niceid

Optional integrations:

pip install django-niceid[drf]      # Django REST Framework
pip install django-niceid[ninja]    # Django Ninja
pip install django-niceid[pydantic] # Pydantic v2 schemas
pip install django-niceid[tortoise] # django-tortoise ORM bridge

Quickstart

Add the app to INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    "niceid.apps.NiceIDConfig",
]

Define a model with a class-level namespace (2–16 lowercase letters or underscores):

from niceid.models import NiceIDModel


class User(NiceIDModel):
    namespace = "user"

    class Meta:
        # your options
        pass

Each row gets a primary key like user_1KGGWGM8FEABRJA533GJKYW0B. The value is generated by PostgreSQL via db_default=uuidv7() and exposed in Python as a NiceID instance.

PostgreSQL uuidv7()

On PostgreSQL 18+, uuidv7() is available without extra setup. Ensure your database supports it before running migrations:

SELECT uuidv7();

URL converter

The app config registers a path converter named niceid:

from django.urls import path

urlpatterns = [
    path("users/<niceid:user_id>/", user_detail),
]

user_id in the view is a NiceID instance.

Optional integrations

Django REST Framework

from niceid.drf import NiceIDSerializerField, NiceIDRelatedField

class UserSerializer(serializers.ModelSerializer):
    id = NiceIDSerializerField(read_only=True)
    team_id = NiceIDRelatedField(queryset=Team.objects.all(), source="team")

Django Ninja

Install django-niceid[ninja]. Field registration runs automatically in NiceIDConfig.ready().

Pydantic

Install django-niceid[pydantic]:

from pydantic import BaseModel
from niceid import NiceID

class Payload(BaseModel):
    user_id: NiceID

ID format

Part Rule
Namespace [a-z_]{2,16}
Separator _
Encoded UUID 25 Crockford base32 characters (UUIDv7)

Example: user_1KGGWGM8FEABRJA533GJKYW0B

Limitations (v0.1.0)

  • PostgreSQL only for database fields (native UUID column + uuidv7() default).
  • Python 3.14+ only.
  • Non-primary-key NiceIDField usage requires an explicit namespace= on the field.

Development

pip install -e ".[dev]"
pytest -m "not postgres"
docker compose up -d
POSTGRES_HOST=localhost POSTGRES_PORT=54329 pytest -m postgres

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_niceid-0.3.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_niceid-0.3.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file django_niceid-0.3.0.tar.gz.

File metadata

  • Download URL: django_niceid-0.3.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_niceid-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a77132a6371855e61898fe75f883af5a952ea90654877462b0f3e1861064c9fa
MD5 c16a51826353aba1d3e92e845dc9358b
BLAKE2b-256 3f1510fde5ff15cf0c8070405855643e1dc38168556a5cb4af81c5937f6ab45d

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_niceid-0.3.0.tar.gz:

Publisher: release.yml on owais/django-niceid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_niceid-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: django_niceid-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_niceid-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 37021ef7b66dcac053c0ecaca6cca5703cd29c5d2180c5aac40c63603d262b36
MD5 00dacec580f2152d105d68106b30581b
BLAKE2b-256 dc451d08f4e8b77263356a6142f4401ac1ebdf31c126358be513f9fd5d2acc53

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_niceid-0.3.0-py3-none-any.whl:

Publisher: release.yml on owais/django-niceid

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page