我有两个模型“问题”和“字体”。在这些“问题”中,是不可删除的模型。而Question引用了Font。
因此,如果删除字体,则该字体的参考号将设置为无,如果删除问题,则由于该问题是不可删除的模型,因此不会从数据库中删除,其活动字段将设置为错误,因此无法通过Django的“对象”模型管理器查询。在这种情况下,如果我删除一个问题,然后再删除字体,则会抛出“ IntegrityError”,因为软删除的问题仍然引用该字体。
问题是我无法在单元测试中重现此问题。在单元测试中,字体被正常删除。 在前端,我得到以下信息。
update or delete on table "custom_fonts_customfont" violates foreign key constraint "font_id_refs_id_794a5361" on table "questions_question"
DETAIL: Key (id)=(1026) is still referenced from table "questions_question".
我尝试使用Django的Transaction测试用例,还确保在测试用例中将该问题软删除,并使用Django的“未过滤”模型管理器确认问题对字体的引用。
class Question(ExtendedOrderedModel, NonDeletableModel):
font = models.ForeignKey('custom_fonts.CustomFont', null=True, on_delete=models.SET_NULL)
这是我的测试用例
def test_font_deletion_after_question_deletion_(self):
self.question.font = CustomFont.objects.create(
name='roboto', font_type='truetype', path='font.ttf', created_by=self.owner
)
self.question.save()
self.question.delete()
CustomFont.objects.all().delete() # This should raise an error but it is not raising
print(Question.objects.all()) # []
print(Question.unfiltered.first().font_id) # 1
答案 0 :(得分:0)
最后,我找到了原因。是因为
在Postgresql中,将约束设置为DEFERRABLE INITIALIALLY DEFERRED。这个 使它仅在事务处理时检查那些约束 承诺。 (这可能也会影响Oracle后端, 搜索。)这会导致TestCase出现问题:因为它们永远不会 承诺,永远不会触发许多违反约束的情况。
在测试用例中添加以下几行对我有帮助。
cursor = connection.cursor()
cursor.execute('SET CONSTRAINTS ALL IMMEDIATE')