2016-02-18 3 views
0

Я пытаюсь построить представление, где формы загружаются динамически на основе пула форм, доступные формы определены в списке кортежей, подобных этому, это предназначено для ускорения разработки новых форм в «рамочный» способ:Python неожиданное поведение импорта

#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") 

мнение определяется в 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 работало, но я нахожу это решение очень монолитным и непитоновым.
+0

Я вижу циклический импорт в вашей трассе стека, идущий 'forms -> utils -> installed_io -> forms'. Они вызывают всевозможные головные боли при инициализации, возможно, включая проблему, которую вы видите здесь. Избегайте их, если это вообще возможно. – user2357112

+3

Это пахнет круговым импортом или ошибкой в ​​самом файле FileForm. Попробуйте запустить оболочку './manage.py shell' и' from .. import FileForm', чтобы убедиться, что она работает независимо. Затем попробуйте 'from utils import get_input_form' в вашей оболочке. –

+0

manage.py shell будет генерировать одно и то же исключение, слияние как utils.py, так и installed_io.py в views.py решит проблему импорта. –

ответ

0

На основе комментариев на оригинальный пост я сделал следующие изменения в мой код:

вместо того, чтобы импортировать классы на installed_io модуле я использовал строки:

#installed_io.py 
forms = [("json","JsonForm"),("csv","CsvForm"),....] 

тогда я изменил утилиты. py, чтобы импортировать класс из строки:

from installed_io import installed_inputs  

def get_input_form(slug): 
    for entry in installed_inputs: 
     if entry[0] == slug: 
      module = importlib.import_module("tensorflow_board_django.io.forms") 
      class_name = entry[1] 
      return getattr(module, class_name) 
    raise NotImplementedError("The required form is not implemented or missing from the installed inputs") 
Смежные вопросы