【问题标题】:Save model tries to create new object保存模型尝试创建新对象
【发布时间】:2017-06-15 14:50:30
【问题描述】:

我有以下两个 Django 模型:

class A:
    uuid = CharField(primary_key=True)
    code = CharField(unique=True)

class B:
    uuid = CharField(primary_key=True)
    a = ForeignKey(A, related_name='bs')

    def save(**kwargs):
        self.a.save(**kwargs)
        super(B, self).save(**kwargs)

如果我想在测试用例中使用它们并编写这个函数:

def setUp():
    a = A.objects.create(uuid='a')
    b = B.objects.create(uuid='b', a=a)

我收到以下错误:

UNIQUE constraint failed: app_name_a.code

看起来在 B 的 save 方法中,它尝试创建另一个具有相同值的 A,而不是更新现有实例。为什么会这样?我正在使用 Python 3.5 和 Django 1.8.14。

顺便说一句:我想保存父级的原因是我在 save 方法中有更新 updated_at 时间戳的功能。

【问题讨论】:

    标签: python django model


    【解决方案1】:

    问题出在kwargs 你传入A.save()

    self.a.save(**kwargs)
    

    如果您查看documentation,您会看到force_insert 被发送True (因为此时正在创建A 当您尝试保存@987654328 @ 所以 Django 不会检查 self.a 是否已经创建,因为您也将 force_insert 作为 True 传递给 self.a.save()

    要解决此问题,您不应传递 **kwargs 以便让 Django 决定创建或更新 self.a

    def save(self, *args, **kwargs):
        self.a.save()
        super(B, self).save(*args, **kwargs)
    

    【讨论】:

    • 在您提到的文档中似乎默认为force_insert=False,但实际上,当我打印kwargs 时,我看到它确实设置并设置为True!
    • @physicalattraction 它将被发送到 True,因为 Django 根据 self.pk 是否为 None 设置该值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    相关资源
    最近更新 更多