按照原始写法如下:
id = UUIDField(default=uuid.uuid1, editable=False, primary_key=True)
这样存进去之后,我们发现了2个问题:
1 我们观察数据库,发现数据库里该字段长度为32位。
2 存进去的是hex格式
而我们想要存为类似a24c738f-3eb3-11eb-8cb6-e454e8c75352格式的,怎么办呢?
首先,我们要解决一个问题是字段长度,否则首先长度就超过了。
这里,我们观察了UUIDField的源码,主要问题出在了下面一段代码:
def get_internal_type(self):
return "UUIDField"
我们接着去看Field源码里的get_internal_type
def get_internal_type(self):
return self.__class__.__name__
从代码看出来,我们要去看看我们的class名字了,这里我们不重写,返回的就是UUIDField字符串
我们接着从源码里面看看:
data_types = {
'AutoField': 'integer AUTO_INCREMENT',
'BigAutoField': 'bigint AUTO_INCREMENT',
'BinaryField': 'longblob',
'BooleanField': 'bool',
'CharField': 'varchar(%(max_length)s)',
'DateField': 'date',
'DateTimeField': 'datetime(6)',
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
'FilePathField': 'varchar(%(max_length)s)',
'FloatField': 'double precision',
'IntegerField': 'integer',
'BigIntegerField': 'bigint',
'IPAddressField': 'char(15)',
'GenericIPAddressField': 'char(39)',
'JSONField': 'json',
'NullBooleanField': 'bool',
'OneToOneField': 'integer',
'PositiveBigIntegerField': 'bigint UNSIGNED',
'PositiveIntegerField': 'integer UNSIGNED',
'PositiveSmallIntegerField': 'smallint UNSIGNED',
'SlugField': 'varchar(%(max_length)s)',
'SmallAutoField': 'smallint AUTO_INCREMENT',
'SmallIntegerField': 'smallint',
'TextField': 'longtext',
'TimeField': 'time(6)',
'UUIDField': 'char(32)',
}
OK,这里可以看出默认生成的是32位的char类型,所以我们需要重写该方法:
def get_internal_type(self):
return "CharField"
我们直接用CharField代替,OK,下一步,我们要简化我们的代码,所以继续看源码,我们需要修改__init__函数
def __init__(self, verbose_name=None, **kwargs):
kwargs['max_length'] = 100
kwargs['default'] = uuid.uuid1
kwargs['primary_key'] = True
kwargs['editable'] = False
super().__init__(verbose_name, **kwargs)
这样,我们就无需指定长度和其他属性了,每次使用只需要申明即可。
OK,这是我们继承Field时需要的用法。但我们可以直接偷懒,改为CharField即可。如此的话,我们就无需重写大部分方法,只需要重新__init__即可。
然后使用就简单了,如下:
id = UUIDField()
对于主键ID,我们做的相关项目都是固定的,也就无需添加任何参数了。