How to handle prefixed UUIDs in Django Admin for querying and displaying objects?

I am working on a Django project with a custom UUIDField with a prefix (e.g., ft_) to represent IDs. The raw UUID is stored in the database, but I want the prefixed value (e.g., ft_) to be shown in API responses, admin interfaces, and elsewhere. However, this creates issues when querying objects in Django Admin because the URLs include the prefixed ID, and Django tries to query the database directly using this prefixed value.

Here is my custom field implementation:

import uuid
from django.db import models

class PrefixedUUIDField(models.UUIDField):
    def __init__(self, prefix, *args, **kwargs):
        self.prefix = prefix
        super().__init__(*args, **kwargs)

    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return f"{self.prefix}_{value}"

    def get_prep_value(self, value):
        if isinstance(value, str) and value.startswith(f"{self.prefix}_"):
            value = value.split(f"{self.prefix}_")[1]
        return super().get_prep_value(value)

    def to_python(self, value):
        if isinstance(value, uuid.UUID):
            return f"{self.prefix}_{value.hex}"
        if isinstance(value, str) and not value.startswith(f"{self.prefix}_"):
            return f"{self.prefix}_{value}"
        return value

The model:

class FamilyTree(models.Model):
    id = PrefixedUUIDField(prefix="ft", primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=255)

In Django Admin, the URL for editing an object looks like this:

http://admin.localhost:8000/family_tree/familytree/ft_5F5479ca65374d401d9466d57fc95e4072/change/

However, this causes the following error:

invalid input syntax for type uuid: "ft_5F5479ca65374d401d9466d57fc95e4072"

I understand this happens because Django Admin tries to query the database using the prefixed id, but the database expects the raw UUID.

Вернуться на верх