Django - get_or_create 不起作用

6 投票
3 回答
6048 浏览
提问于 2025-04-16 23:48

你能帮我理解一下为什么这段代码会导致重复条目(IntegrityError)吗?

我在用Django 1.2。

(row, is_new) = MyModel.objects.get_or_create(field1=1)
row.other_field = 2
row.save()

我在field1上设置了唯一约束。如果有一行数据是field1=1,所有操作都正常,Django会执行一个“获取”操作。

但如果没有field1=1的那一行,Django似乎会创建这一行,这没问题。但是为什么我不能保存它呢?

更新:

如果这有帮助,这里是MyModel:

class MyModel(models.Model):
    id = models.BigIntegerField(primary_key=True)
    field1 = models.BigIntegerField(unique=True)
    other_field = models.CharField(max_length=765)
    class Meta:
        db_table = u'project_crosses_suppl_FO'

field1是指向另一个表的外键。但是我没有为那个表在Django中创建模型,所以我没有告诉Django它是外键。

3 个回答

2

获取或创建的功能会返回一组结果,即使你用的字段被设置为主键或唯一值。

所以在你的情况下:row 是一个包含一个对象的元组,因此这个方法应该对你有效:

(row, is_new) = MyModel.objects.get_or_create(field1=1)
row[0].other_field = 2
row[0].save()
3

我觉得 get_or_create 这个方法有点问题。所以我在用这个替代的方法:

rows = MyModel.objects.filter(field1=1)
row = rows[0] if rows else MyModel(field1=1)
row.other_field = 2
row.save()
7

假设你提供的代码大致上和真实代码相符,那么不出意外,问题不在于Django,而是在于你的模型。

你把自动生成的主键字段替换成了自己的id字段,但忘记把它设置为自增。所以数据库没有为主键使用新的值,这就导致了完整性错误。

除非你有非常好的理由,否则最好让Django自己处理主键字段。

撰写回答