【发布时间】:2016-02-18 22:21:24
【问题描述】:
我正在尝试构建一个视图,其中基于表单 slug 动态加载表单,可用表单在这样的元组列表中定义,这是为了加快“类似框架”中新表单的开发"方式:
#installed_io.py
forms = [("json",JsonForm),("csv",CsvForm),....]
froms 像往常一样在 forms.py 模块中定义。
from django import forms
class FileForm(BaseDatasetForm):
file = forms.FileField(label="Opcion 1: Seleccione un archivo", required=False)
text = forms.CharField(widget=forms.Textarea, label="Opction 2: Introduzca el contenido en este campo", required=False)
utils.py 定义了动态选择Form类的函数:
from installed_io import installed_inputs
def get_input_form(slug):
for entry in installed_inputs:
if entry[0] == slug:
return entry[1]
raise NotImplementedError("The required form is not implemented or missing from the installed inputs")
视图是在我的 django 应用的 views.py 模块中定义的:
#views.py
from utils import get_input_form
@login_required
def add(request, slug):
InputForm = get_input_form(slug)
if request.method == "POST":
form = InputForm(request.POST, request.FILES)
if form.is_valid():
object_id = form.save()
messages.success(request, "Dataset created")
return redirect(reverse("input:dataset", args=[str(object_id.inserted_id)]))
else:
form = InputForm()
return render(request, "datasets/add-form.html", {"form":form})
但我收到此导入错误:
python manage.py runserver
Unhandled exception in thread started by <function wrapper at 0x7fe9c465c398>
Traceback (most recent call last):
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 109, in inner_run
autoreload.raise_last_exception()
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 249, in raise_last_exception
six.reraise(*_exception)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 226, in wrapper
fn(*args, **kwargs)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/__init__.py", line 18, in setup
apps.populate(settings.INSTALLED_APPS)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models(all_models)
File "/home/jesus/workspace/tensorflow-board-django/venv/local/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
self.models_module = import_module(models_module_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/analysis/models.py", line 2, in <module>
from ..input.forms import SOURCES
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/forms.py", line 2, in <module>
from utils import save_dataset
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/utils.py", line 2, in <module>
from installed_io import installed_inputs
File "/home/jesus/workspace/tensorflow-board-django/tensorflow_board_django/input/installed_io.py", line 1, in <module>
from forms import FileForm
ImportError: cannot import name FileForm
我尝试过的:
- 使用绝对路径更改导入语句
- 删除 pyc 文件
- 使用点符号导入模块
- 尝试将 installed_input 列表保存在 init.py 上
- 只有将所有代码移动到 views.py 文件才有效,但我发现此解决方案非常单一且非 Python 化。
【问题讨论】:
-
我在您的堆栈跟踪中看到循环导入,转到
forms -> utils -> installed_io -> forms。这些会导致各种初始化顺序问题,可能包括您在此处看到的问题。尽可能避免使用它们。 -
那是
circular import的味道,或者是 FileForm 本身的错误。尝试运行 shell./manage.py shell和from .. import FileForm以确保它们独立工作。然后在你的 shell 中尝试from utils import get_input_form。 -
manage.py shell 会抛出同样的异常,将 utils.py 和 installed_io.py 合并到 views.py 确实解决了导入问题。
-
您可以在闭包中(在函数调用中)进行输入以进行测试,但我建议您重新编写导入以避免从长远来看任何循环导入。
-
如果您愿意,请以解决这种循环依赖的最佳方式发布对此答案的回复,否则我将在稍后发布我的解决方案。
标签: python django python-2.7 python-import