如果相关外键不存在,如何禁止创建对象?
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
.
这是设置
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
.