Python 当作为外键访问时,自定义UUID字段PK返回错误的类型

Python 当作为外键访问时,自定义UUID字段PK返回错误的类型,python,python-3.x,django,Python,Python 3.x,Django,我需要一个UUID pk,由于一些序列化问题,我正在考虑只在DB中使用UUID,在DB之外使用字符串 我已经创建了这个自定义字段,它完全允许这样做 import uuid from typing import Union from django.db import models class CustomUUIDField(models.UUIDField): """ In database: uuid Outside of a data

我需要一个UUID pk,由于一些序列化问题,我正在考虑只在DB中使用UUID,在DB之外使用字符串

我已经创建了这个自定义字段,它完全允许这样做

import uuid
from typing import Union

from django.db import models


class CustomUUIDField(models.UUIDField):
    """
    In database: uuid
    Outside of a database: str
    """
    description = "Custom UUID field which is an UUID only in DB and a string outside of it"

    @staticmethod
    def _serialize_value(value: Union[str, uuid.UUID]) -> str:
        return str(value)

    @staticmethod
    def _deserialize_value(value: Union[str, uuid.UUID]) -> uuid.UUID:
        if isinstance(value, str):
            value = uuid.UUID(value, version=4)
        return value

    def to_python(self, value) -> str:
        return self._serialize_value(value)

    def from_db_value(self, value, expression, connection) -> str:
        return self._serialize_value(value)

    def get_prep_value(self, value) -> str:
        return self._serialize_value(value)

    def value_to_string(self, obj):
        value = self.value_from_object(obj)
        return self.get_prep_value(value)

    def get_db_prep_value(self, value, connection, prepared=False) -> uuid.UUID:
        return self._deserialize_value(value)


class UUIDMixin(models.Model):
    id = CustomUUIDField(default=uuid.uuid4, primary_key=True, editable=False)

    class Meta:
        abstract = True

    def is_new(self) -> bool:
        return self._state.adding

    def __str__(self):
        return f"<{self.__class__.__qualname__}: {self.id}>"
不一致的是:

a.id
返回一个字符串。
b.id
返回一个字符串。
b.a.id
返回UUID

我是否忘记覆盖自定义字段中的方法?如果没有一些讨厌的黑客,我期望的行为是可行的吗

Django 3.0.8

编辑:我认为这是行不通的。我放弃了这个想法,按照预期使用UUID

编辑2:我想在这里添加两件事

我试过了

@CustomUUIDField.register_lookup
class IDCase(Transform):
    lookup_name = 'id'
    function = 'CAST'
    bilateral = True

    def as_sql(self, compiler, connection):
        sql, params = compiler.compile(self.lhs)
        sql = 'CAST(%s AS TEXT)' % sql
        return sql, params

    @property
    def output_field(self):
        return CharField()
它也不起作用

同样,这个例子也不完全正确。我认为如果你获取这样的数据,它就会正常工作。但在Auth中间件中,如果我执行
request.user.company.id
,那么它就是UUID,因此它必须取决于ORM如何构造查询

@CustomUUIDField.register_lookup
class IDCase(Transform):
    lookup_name = 'id'
    function = 'CAST'
    bilateral = True

    def as_sql(self, compiler, connection):
        sql, params = compiler.compile(self.lhs)
        sql = 'CAST(%s AS TEXT)' % sql
        return sql, params

    @property
    def output_field(self):
        return CharField()