代码之家  ›  专栏  ›  技术社区  ›  Hanny

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

  •  0
  • Hanny  · 技术社区  · 5 年前

    我的表单有一个测试出错了,因为我的表单选项是从模型中填充的。错误如下:

    ../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"}
    

    这是个大禁忌吗?我怎样才能绕过这个问题,这样我的测试才能真正运行?

    这个错误会在我的测试运行之前弹出,所以它会在我的导入语句中发生。

    如果我改变 [(ey.end_year, ey.full_label()) for ey in Year.objects.all()] [] 我的测试按预期运行,但我不想在 forms.py 只是为了测试…

    1 回复  |  直到 5 年前
        1
  •  1
  •   Alasdair    5 年前

    在你的选择中使用callable。

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