Python 当作为外键访问时,自定义UUID字段PK返回错误的类型
我需要一个UUID pk,由于一些序列化问题,我正在考虑只在DB中使用UUID,在DB之外使用字符串 我已经创建了这个自定义字段,它完全允许这样做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
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()