如果相关外键不存在,如何禁止创建对象?

How to disallow creation of object if related foreign key doesn't exists?

这是设置

class A(Model):
    pass

class B(Model):
    a = ForeignKey(A, on_delete=CASCADE)


assert A.objects.all().count() == 0
try:
    B.object.create(a_id=1)
except IntegrityError:
    print('error')
    # ... another logic to deal with situation

数据库是 PostgreSQL。还没有 A 个对象(至少 id=1)。

我尝试使用从第 3 方获取的某个假设对象 A 的 ID 创建对象 B

预期

如果没有对象 A -> 抛出 IntegrityError -> 处理它(例如用 id=1 创建对象 A 并重新运行)。

现实

对象 B 无论如何都会创建,尽管有外键约束,会抛出 IntegrityError (Key (a_id)=(1) is not present in table "app_a") 但不会被 try/except 获取。一切都搞砸了。


我事先不知道要 get_or_create 对象 A 什么,因为每次我想创建 B 时都会得到 2 个查询(而且我需要创建很多次,而大部分时间需要的对象 A 已经在数据库中)


编辑 1

事实证明,问题出在 pytest 上。只有内部测试我无法捕捉 IntegrityError.

with pytest.raises(IntegrityError):
  b = B.objects.create(a_id=1)

尽管 id=1 没有 A 对象,但上面的代码没有引发 IntegrityError。尽管如此,IntegrityError 的回溯信息还是在控制台中打印出来了。并创建了对象 b

问题在于尝试在原子事务中捕获 IntegrityError

来自 pytest helped 的人修复它 @pytest.mark.django_db(transaction=True) 而不是 @pytest.mark.django_db.