在Django中UUIDField类型的字段可以作为主键(主键是绝对不可能为NULL值的)使用,这个是丝毫没问题的,但是如果其他非主键字段使用UUIDField类型,则最好是将这个字段的默认值设置成Python中的None类型,即default=None,设置范例如下:
UUIDField为主键的设置范例:
idappasswd = models.UUIDField(primary_key=True, auto_created=True, default=uuid.uuid4, editable=False)
非空字段类型为UUIDField时,必须设置default=某个UUID的值,可以是uuid4(),也可以是别的uuid值,设置范例如下:
appuuid = models.UUIDField(default=uuid.uuid4, null=False,
verbose_name=u'app uuid',
help_text="app uuid")
可以为空的UUIDField字段类型的设置范例:
associatedappuuid = models.UUIDField(default=None, null=True, blank=True,
verbose_name=u'associated uuid',
help_text="associated app uuid")
代码注解:上面的三行代码中,idappasswd 是作为主键使用,appuuid 是app的UUID不能为空,associatedappuuid 作为app的关联UUID,如果没有关联,因此可以为空。
因为UUIDField的内容如果不为None,则会被Django进行严格检查(此处应该不能认为是bug或issue),验证的代码如下:
django/db/backends/mysql/operations.py 211行左右:
def convert_uuidfield_value(self, value, expression, connection, context):
if value is not None:
value = uuid.UUID(value)
return value
如果value不是None,则会进行执行uuid.UUID()函数,如果参数value不为None,则会在uuid.py模块中的__init__中raise异常ValueError badly formed hexadecimal UUID string。
总结:
1.排查问题的要领是不断的缩小问题存在的范围,一定要使用排除法,这个要时刻牢记。
2.如果某个字段的类型是UUIDField,并且设置为空,则最好将其设置为null=True,并且建议设置default=None。