Django 1.9更新模型对象创建一个新的对象实例

时间:2016-02-11 22:25:13

标签: python django

我正在使用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模型的主键。这可能是为什么它不是更新,而是创建一个全新的条目?

2 个答案:

答案 0 :(得分:2)

主键是Django用来确定是更新还是创建项目的主键。通常,这是一个您不会修改的不透明ID;但在您的情况下,它是您数据的一部分。修改该值时,Django无法知道该对象是否引用了数据库中的现有行。

不要这样做;坚持使用与您的实际数据无关的自动增量ID。

答案 1 :(得分: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'>]

如果可能,我建议删除primary_key=True字段上的name属性。如果您希望name是唯一的,可能只需设置unique=True