2016-02-11 169 views
0

我正在使用Django 1.9,並注意到使用模型時出現了一些奇怪的行爲。我知道下面的代碼創建一個對象,將其保存到數據庫,改變了場,然後更新數據庫中相同的條目:Django 1.9更新模型對象創建一個新對象實例

cat = models.Cat(name="Bob") 
cat.save() 
cat.name = "Sally" 
cat.save() 

然而,當我查詢使用cats = models.Cat.objects.all()我的所有對象,我覺得,與其比返回["Sally"]它實際上返回["Bob", "Sally"]。顯然cat.save()正在數據庫中創建一個新元素,而不是更新現有元素。我以前曾與Django合作過,但從未遇到過這個問題。需要注意的一點是,name屬性是Cat模型的主鍵。這可能是爲什麼它沒有更新,但創建一個全新的條目?

回答

1

你說的沒錯,這裏的問題是,你的主鍵是name場。如果數據庫中存在pk值,Django將執行更新,如果不存在,則會執行插入。例如:

class Cat(models.Model): 
    name = models.CharField(max_length=255) 

cat = Cat(name='Bart') 
cat.save() # This creates a new object 
print(cat.pk) 
> '1' 

cat.name = 'Sally' 
cat.save() # This updates the object, the pk will still be '1' 
print(cat.pk) 
> '1' 

print(Cat.objects.all()) 
> [<Cat 'Sally'>] 

fluffy = Cat(name='Fluffy') 
fluffy.pk = 1 
fluffy.save() 
'''This will UPDATE the existing object, since an object 
with that primary key already exists''' 
print(Cat.objects.all()) 
> [<Cat 'Fluffy'>] 

fluffy.pk = 2 
fluffy.save() 
'''This will CREATE a new object, since no object with 
that primary key already exists''' 

print(Cat.objects.all()) 
> [<Cat 'Fluffy'>, <Cat 'Fluffy'>] 

如果可能的話,我會建議刪除對nameprimary_key=True屬性。如果你想name是唯一的,也許只是設置unique=True而不是?

2

主鍵是什麼Django使用,以確定是否更新或創建一個項目。通常,這是一個你不會修改的不透明ID;但在你的情況下,它是你的數據的一部分。修改該值時,Django無法知道該對象是否引用數據庫中的現有行。

不要這樣做;堅持與您的實際數據無關的自動增加的ID。

相關問題