Django测试无法运行:表单ChoiceField关联模型时提示表不存在
解决Django测试中表单触发的
no such table错误 这个问题我之前也碰到过,核心原因是表单定义的时机不对——你直接在ChoiceField的choices参数里执行了数据库查询,而Django的测试流程里,数据库表是在测试开始前才完成迁移创建的,可你的表单类在模块加载的时候就已经跑了Year.objects.all(),这时候common_year表还压根不存在,所以就抛出了这个OperationalError。
下面给你两个靠谱的解决办法:
方法一:在表单__init__方法中动态设置choices
把数据库查询延迟到表单实例化的时候执行,这时候测试环境的数据库表已经创建完成了:
from django import forms from .models import Year class Dashboard(forms.Form): year = forms.ChoiceField(choices=[]) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 仅当创建表单实例时才查询数据库 self.fields['year'].choices = Year.objects.all().values_list('pk', 'year')
方法二:使用可调用对象作为choices(Django 3.2+适用)
如果你的Django版本是3.2及以上,可以直接把一个函数(不带括号)传给choices参数,Django会在需要渲染表单或验证数据的时候才调用这个函数,完美避开模块加载时的数据库查询:
from django import forms from .models import Year def get_year_choices(): return Year.objects.all().values_list('pk', 'year') class Dashboard(forms.Form): year = forms.ChoiceField(choices=get_year_choices)
额外提示
如果你的测试用例需要Year模型的测试数据,记得在测试类的setUp方法里创建对应的测试实例,不然表单的year选项会是空的,但至少不会再抛出表不存在的错误了。
内容的提问来源于stack exchange,提问作者Lucas Garcia De Araújo Martins
相关产品推荐
相关产品推荐

