测试从Django中的数据库中获取选择的表单-不允许数据库访问

时间:2019-09-05 16:12:39

标签: python django django-forms pytest

我有一个错误的表单测试,因为我有从模型中填充的表单选项。错误看起来像这样:

../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中的内容...

1 个答案:

答案 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加载时发生的,这可能会在迁移新数据库时导致错误,或者导致过时的结果。