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

相關文章
相關標籤/搜索