UUIDField在Django Model中的使用经验

    今天下午在将数据库从旧库导入到新库时,完成后发现Django网站没法打开,报“ValueError, badly formed hexadecimal UUID string”,最终定位到缘由是一个UUIDField类型字段的值为0,形成Django没法将0验证为UUID类型,从而引起ValueError异常。现总结UUIDField在Django Model中的使用经验以下。python

    在Django中UUIDField类型的字段能够做为主键(主键是绝对不可能为NULL值的)使用,这个是丝毫没问题的,可是若是其余非主键字段使用UUIDField类型,则最好是将这个字段的默认值设置成Python中的None类型,即default=None,设置范例以下:mysql

UUIDField为主键的设置范例:sql

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字段类型的设置范例:express

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,若是没有关联,所以能够为空。
使用注意:
1.在MySQL数据库中UUIDField类型必定是32位的char类型,在数据库Model中,开发者不须要设置max_length=xxx,由于这个max_length的数值默认的必定是32。
2.若是某个字段的类型是UUIDField,而且设置为空,则最好将其设置为null=True,在数据库中,此字段的值不能为空('')也不能为0(数字0),而且建议设置default=None。
3.以上内容在Django 1.10.3上通过测试
由于UUIDField的内容若是不为None,则会被Django进行严格检查(此处应该不能认为是bug或issue),验证的代码以下:
django/db/backends/mysql/operations.py 211行左右:
django

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。
tag:Django UUIDField, Django ValueError, badly formed hexadecimal UUID string
--end--

app

相关文章
相关标签/搜索