2012-02-17 3 views
7

У меня есть модель project_phase:Джанго модели рекурсивный импорт - как разрешить

from django.db import models 
    from django.utils import simplejson 
    from core.models import pmo_review_task 

он ссылается pmo_review_task (потому что он создает pmo_review_task в его сохранить ovewrite)

from django.db import models 
from datetime import datetime 
from django.contrib.auth.models import User 
from core.models import sc_review_task 

который ссылки sc_review_task, который ссылается на project_phase (потому что он создает project_phase в его сохранении ovewrite)

from django.db import models 
from core.models import project_phase 

так заканчивается project_phase импорт pmo_review_task импорт sc_review_task импорт project_phase, и я предполагаю, что петли как-нибудь генерировать эту ошибку:

Unhandled exception in thread started by <bound method Command.inner_run of <django.core.management.commands.runserver.Command object at 0x010ACFB0>> 
Traceback (most recent call last): 
    File "C:\Python27\lib\site-packages\django\core\management\commands\runserver.py", line 88, in inner_run 
    self.validate(display_num_errors=True) 
    File "C:\Python27\lib\site-packages\django\core\management\base.py", line 249, in validate 
    num_errors = get_validation_errors(s, app) 
    File "C:\Python27\lib\site-packages\django\core\management\validation.py", line 35, in get_validation_errors 
    for (app_name, error) in get_app_errors().items(): 
    File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 146, in get_app_errors 
    self._populate() 
    File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 64, in _populate 
    self.load_app(app_name) 
    File "C:\Python27\lib\site-packages\django\db\models\loading.py", line 78, in load_app 
    models = import_module('.models', app_name) 
    File "C:\Python27\lib\site-packages\django\utils\importlib.py", line 35, in import_module 
    __import__(name) 
    File "C:\work\Portman\core\models\__init__.py", line 4, in <module> 
    from pmo_review_task import pmo_review_task 
    File "C:\work\Portman\core\models\pmo_review_task.py", line 5, in <module> 
    from core.models import sc_review_task 
    File "C:\work\Portman\core\models\sc_review_task.py", line 3, in <module> 
    from core.models import project_phase 
    File "C:\work\Portman\core\models\project_phase.py", line 4, in <module> 
    from core.models import pmo_review_task 
ImportError: cannot import name pmo_review_task 

Как преодолеть это?

+0

Почему эти три модели в отдельных файлах? Вы пытаетесь создать архитектуру типа «одна модель для каждого файла»? Зачем? –

ответ

17

Два способа:

  1. импорта модели внутри метода (как это было предложено @YujiTomita).
  2. Чтобы использовать функцию get_model из django.db.models, которая предназначена для ленивых импорта модели .:

    project_phase = get_model('core', 'project_phase') 
    

Я предпочитаю второй, но оба метода хорошо.

+0

Да, я полагаю, это более подходящий ответ, поскольку в названии вопроса конкретно упоминается рекурсивный импорт модели django. +1 –

+0

Первый путь дороже? Я имею в виду, что будет импорт каждого вызова функции. – sunprophit

+0

@sunprophit Я не могу сказать, какие из них будут более «дорогими», так как стоимость любого из этих методов будет незначительной (по сравнению с другими операциями в вашем коде, например, взаимодействием с БД). Читаемость или ваш личный вкус являются более ценными факторами здесь. – DrTyrsa

6

импорт project_phase внутри save способ.

Импорт вызывается всякий раз, когда выполняется код.

Если он находится в глобальном пространстве имен модулей (вверху), то он вызывается сразу, и вы будете иметь проблемы с циклическим импортом, поскольку вы описываете, потому что один файл импортирует другой файл, который импортирует исходный файл.

Если вы поставили задачу импорта проблемы внутри функции, она/не/вызвана при импорте файла.

import foo # executed upon importing this file. 

def import_foo_when_called(): 
    import foo # only executed when function is called, thus no problems when 
       # another module imports this file. 
Смежные вопросы