2012-02-17 19 views
7

que tienen un modelo project_phase:modelos de Django importaciones recursivas - cómo resolver

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

que hace referencia pmo_review_task (ya que crea una pmo_review_task en su guardar ovewrite)

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

cuales referencias sc_review_task que hace referencia a project_phase (porque crea un project_phase en su sobreescribir)

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

por lo que termina project_phase importaciones pmo_review_task importaciones sc_review_task importaciones project_phase y supongo que se realiza un bucle hasta la generación de alguna manera este error:

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 

cómo puedo superar esto?

+0

¿Por qué estos tres modelos están en archivos separados? ¿Estás tratando de tener un tipo de arquitectura de "un modelo por archivo"? ¿Por qué? –

Respuesta

17

dos maneras:

  1. Para importar un modelo dentro de un método (como se sugiere @YujiTomita).
  2. Para utilizar la función de get_modeldjango.db.models que está diseñado para las importaciones modelo perezosos .:

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

Yo prefiero la segunda, pero ambos métodos están bien.

+0

Sí, supongo que esta es la respuesta más adecuada ya que el título de la pregunta menciona específicamente las importaciones recursivas del modelo django. +1 –

+0

¿Es en primer lugar más caro? Quiero decir que habrá import cada llamada de función. – sunprophit

+0

@sunprophit No puedo decir cuál de ellos es más "caro", ya que el costo de cualquiera de estos métodos será insignificante (en comparación con otras operaciones en su código, como la comunicación con DB). La legibilidad o su gusto personal son factores más valiosos aquí. – DrTyrsa

6

importa project_phase dentro del método save.

La importación se invoca siempre que se ejecuta el código.

Si está en el espacio de nombres del módulo global (en la parte superior) se llamará de inmediato y tendrá problemas de importación circular como usted describe porque un archivo importa otro archivo que importa el archivo original.

Si coloca la instrucción de importación problemática dentro de una función, es/no/se invoca al importar el archivo.

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.