我有一个错误的表单测试,因为我有从模型中填充的表单选项。错误看起来像这样:
../myapp/tests/test_forms.py:5: in <module>
from myapp.forms import AssignmentForm, AssignmentFormSet
myapp/forms.py:135: in <module>
class MyDetailForm(forms.ModelForm):
myapp/forms.py:138: in MyDetailForm
choices=[(ey.end_year, ey.full_label()) for ey in Year.objects.all()]
venv/lib/python3.7/site-packages/django/db/models/query.py:268: in __iter__
self._fetch_all()
venv/lib/python3.7/site-packages/django/db/models/query.py:1186: in _fetch_all
self._result_cache = list(self._iterable_class(self))
venv/lib/python3.7/site-packages/django/db/models/query.py:54: in __iter__
results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
venv/lib/python3.7/site-packages/django/db/models/sql/compiler.py:1063: in execute_sql
cursor = self.connection.cursor()
venv/lib/python3.7/site-packages/django/db/backends/base/base.py:255: in cursor
return self._cursor()
venv/lib/python3.7/site-packages/django/db/backends/base/base.py:232: in _cursor
self.ensure_connection()
E Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
似乎不希望我在Year
中为自己的选择获取MyDetailForm
对象,如下所示:
class MyDetailForm(forms.ModelForm):
end_year = forms.ChoiceField(
choices=[(ey.end_year, ey.full_label()) for ey in Year.objects.all()]
)
class Meta:
model = MyDetail
fields = ["end_year", "is_current"]
labels = {"is_current": "Current Sections"}
这是大禁忌吗?我该如何解决这个问题,这样我的测试才能真正运行?
此错误会在我的测试运行之前弹出,因此发生在我的import语句中。
如果我将[(ey.end_year, ey.full_label()) for ey in Year.objects.all()]
更改为[]
,我的测试将按预期运行,但是我不想仅出于测试目的而更改forms.py
中的内容...
答案 0 :(得分:1)
在选择中使用呼叫对象。
def get_year_choices():
return [(ey.end_year, ey.full_label()) for ey in Year.objects.all()]
class MyDetailForm(forms.ModelForm):
end_year = forms.ChoiceField(
choices=get_year_choices
)
然后您可以在测试中修补get_year_choices
。
将代码移动到可调用对象还意味着在实例化表单时将查询数据库。目前,查询是在Django加载时发生的,这可能会在迁移新数据库时导致错误,或者导致过时的结果。