Exceptions¶
All exceptions inherit from both DisplayIDLookupError and a standard
Django/Python exception, so you can catch them with either:
from django_display_ids import ObjectNotFoundError
# Catch with library-specific type
except ObjectNotFoundError: ...
# Or catch with Django's built-in type
except ObjectDoesNotExist: ...
Exception Hierarchy¶
DisplayIDLookupError
├── InvalidIdentifierError (+ ValueError)
├── UnknownPrefixError (+ ValueError)
├── MissingPrefixError (+ ImproperlyConfigured)
├── ObjectNotFoundError (+ ObjectDoesNotExist)
└── AmbiguousIdentifierError (+ MultipleObjectsReturned)
Django/Python Base Classes¶
Each exception inherits from the Django or Python exception that best matches its semantics:
Exception |
Django/Python Base |
Why |
|---|---|---|
|
|
Bad input — can’t parse the identifier |
|
|
Bad input — wrong prefix |
|
|
Configuration problem — no prefix set |
|
|
No matching database record |
|
|
Multiple records match |
This means existing except clauses work naturally:
from django.core.exceptions import ObjectDoesNotExist
try:
invoice = Invoice.objects.get_by_identifier("inv_xxx")
except ObjectDoesNotExist:
# Catches ObjectNotFoundError from display ID lookups
# AND model.DoesNotExist from regular .get() calls
...
Exception Classes¶
InvalidIdentifierError¶
Raised when the identifier cannot be parsed by any strategy.
from django_display_ids import InvalidIdentifierError
try:
invoice = resolve_object(Invoice, "not-valid-anything", prefix="inv")
except InvalidIdentifierError:
# Handle invalid input
except ValueError:
# Also works — InvalidIdentifierError IS a ValueError
UnknownPrefixError¶
Raised when a display ID has a prefix that doesn’t match the expected one.
from django_display_ids import UnknownPrefixError
try:
# Expecting "inv" but got "usr"
invoice = resolve_object(Invoice, "usr_2aUyqjCzEIiEcYMKj7TZtw", prefix="inv")
except UnknownPrefixError as e:
print(f"Expected prefix: {e.expected}")
print(f"Got prefix: {e.actual}")
Attributes:
expected— The expected prefixactual— The prefix that was received
MissingPrefixError¶
Raised when a display ID operation is attempted on a model without a prefix.
from django_display_ids import MissingPrefixError
try:
# Order has no display_id_prefix
order = Order.objects.get_by_display_id("ord_xxx")
except MissingPrefixError:
# Configure a prefix on the model
except ImproperlyConfigured:
# Also works
ObjectNotFoundError¶
Raised when no database record matches the resolved identifier.
from django_display_ids import ObjectNotFoundError
try:
invoice = resolve_object(Invoice, "inv_2aUyqjCzEIiEcYMKj7TZtw", prefix="inv")
except ObjectNotFoundError:
# Handle not found
except ObjectDoesNotExist:
# Also works — same as Django's model.DoesNotExist
AmbiguousIdentifierError¶
Raised when multiple records match (typically with slug lookups).
from django_display_ids import AmbiguousIdentifierError
try:
# Multiple invoices have the slug "duplicate-name"
invoice = resolve_object(Invoice, "duplicate-name", strategies=("slug",))
except AmbiguousIdentifierError:
# Handle ambiguity
except MultipleObjectsReturned:
# Also works
QuerySet Methods¶
DisplayIDQuerySet methods (get_by_display_id, get_by_identifier)
raise Model.DoesNotExist and Model.MultipleObjectsReturned, matching
Django’s QuerySet.get() contract:
try:
invoice = Invoice.objects.get_by_identifier("inv_xxx")
except Invoice.DoesNotExist:
# Same as Invoice.objects.get(slug="xxx") — natural Django pattern
The library’s typed exceptions (ObjectNotFoundError, InvalidIdentifierError,
etc.) are still raised by lower-level functions like resolve_object() and
parse_identifier().
Framework-Specific Handling¶
- Django CBVs (
DisplayIDMixin): All exceptions are converted to
Http404.- Django REST Framework (
DisplayIDMixinfromcontrib.rest_framework): ObjectNotFoundError→NotFound(404)Other exceptions →
ParseError(400)
- Django Admin (
DisplayIDAdminSearchMixin): Exceptions are silently caught and the search falls back to normal behavior.