2011-06-16 122 views
5

我有上有此領域的典範:
token = models.CharField(max_length=32, default="", unique=True, null=False, db_index=True)爲什麼Django get_or_create會導致此IntegrityError?

在我使用此方法將該字段設置爲32個字符的隨機字符串保存()方法:

def save(self, *args, **kwargs): 
    if (self.token is None or len(self.token) == 0): 
     self.token = random_identifier() 
    super(SessionPassthrough, self).save(*args, **kwargs) 

def random_identifier(n=32): 
    """ Generate a random identifier of length n. 

    From http://stackoverflow.com/questions/2257441/python-random-string-generation-with-upper-case-letters-and-digits""" 
    return ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(n)) 

不過我得到這個錯誤,每當我試圖創建模型的新實例:
IntegrityError: duplicate key value violates unique constraint "wakelytics_sessionpassthrough_token_key"

創建實例我調用這個方法:

@staticmethod 
def for_session(session): 
    sp, c = SessionPassthrough.objects.get_or_create(session=session) 
    return sp 

get_or_create()在寫入數據庫之前調用方法的save()函數嗎? 答:是的

我得到每當我打電話,第一次的方法有session的IntegrityError,並不斷得到錯誤幾分鐘。然後它會正確返回。這是什麼造成的?

+0

你*知道即使是一個隨機程序也可以選擇一個已經存在的值...對嗎? – 2011-06-16 02:28:31

+0

我知道。但每一次?然後它停止拋出一個錯誤? – 2011-06-16 03:09:31

+0

這是隨機的。你不知道*什麼時候會選擇一個不在數據庫中的值。 – 2011-06-16 03:12:05

回答

1

當然它中。其合同的一部分是它返回一個模型,確實存在,併爲此做它必須保存。

編輯:

你得到錯誤,因爲該值已經存在於數據庫中。

+5

如果它已經存在,那麼get_or_create是否會簡單地返回它?爲什麼提出錯誤? – 2011-06-16 05:53:57

+1

因爲'session'是不同的,所以它是一個單獨的行。 – 2011-06-16 05:55:50