web-dev-qa-db-fra.com

Impossible d'importer des modèles depuis une autre application dans Django

donc j'ai 2 applications en cours d'exécution dans le même projet.

Mes fichiers sont structurés comme suit:

/project_codebase
    /project
        __init.py
        settings.py
        urls.py
        wsgi.py
        ...    
    /app1
        ...
    /app2
        ...
    manage.py

Donc, pour une raison quelconque, j’ai un nom différent pour mon répertoire de base (c’est-à-dire qu’il se termine par codebase). Espérons que ce n'est pas un problème.

Dans mon settings.py , j'ai ceci:

INSTALLED_APPS = [
    ...

    'app1',
    'app2',
]

Ok, donc dans mon models.py (from app2) , je peux facilement importer des modèles depuis app1 avec from app1.models import *. Cependant, lorsque j'utilise from app2.models import * dans mon models.py (depuis app1) , je ImportError.

Des solutions à cela?

10
darkhorse

Cela peut être dû à importation circulaire problèmes. Pour éviter cela, vous devez charger le modèle dynamiquement} _:

Pour versions récentes de Django (1.7+), utilisez le registre d'applications :

from Django.apps import apps
MyModel1 = apps.get_model('app1', 'MyModel1')

Pour versions antérieures de Django (<1.7):

from Django.db.models.loading import get_model
MyModel1 = get_model('app1', 'MyModel1')

Note 1: Si vous souhaitez définir une relation de clé étrangère, il y a aucune instruction d'importation distincte n'est nécessaire Django avez-vous couvert à ce sujet:

Si app1 est une application installée, vous devez définir la relation ForeignKey comme suit:

# in app2.py
class MyModel2(models.Model):
   mymodel1 = models.ForeignKey('app1.MyModel1')

Note 2: Le get_model ne fonctionne que si app1 est une application installée et MyModel1 est le modèle à importer de app1.

Note 3: Essayez d'éviter l'importation de caractères génériques (from ... import *), car c'est une mauvaise pratique .

23
jojo

C'est certainement une importation circulaire.

Mais je pense que ce dont vous avez besoin est d’utiliser des modèles comme une sorte d’arguments RetationFields (ForeignKey, ManyToManyField ou OneToOneField). Vous devez donc ignorer l’importation et l’utiliser comme suit:

# app1/models.py
class Model1(models.Model):
    relation_field = models.ForeignKey('app2.Model2')

De docs :

Si vous devez créer une relation sur un modèle qui n'a pas encore été défini, vous pouvez utiliser le nom du modèle plutôt que l'objet de modèle lui-même.

Pour faire référence à des modèles définis dans une autre application, vous pouvez spécifier explicitement un modèle avec le libellé complet de l'application.

Il suffit de mettre l’objet str comme premier argument des champs de relation qui se basent sur <app_name>.<Model_name>.

Note: il vaut mieux éviter d'importer tout du module (from <module_name> import *)

7
vishes_shell

Si vous souhaitez importer uniquement un module spécifique, n'utilisez pas import *.

Il faudra plus de temps pour charger votre toute la bibliothèque et peut donc aussi affecter la vitesse de votre application.

Si vous souhaitez utiliser quelques modules de votre deuxième application, ajoutez simplement le nom du module à la place de bibliothèques entières, comme ceci:

from app2.models import Module1, Module2

ou il peut s'agir d'un problème d'importation circulaire comme le précisent d'autres.

Merci.

3
Ahmed Ginani

j'utilise ce code toujours et ça marche :)

from position_app.models import Member

2
youssef hassoun

Vous devez spécifier les noms de modèle que vous souhaitez importer, par exemple from app1.models import ModelName1, ModelName2.

1
Terry

Assurez-vous qu'il n'y a pas de conflit de nom entre l'une de vos applications et l'un des modules installés dans votre environnement Python. Si vous utilisez pip, vous pouvez exécuter pip freeze pour afficher une liste des modules installés. 

J'ai eu la même erreur quand une de mes applications s'appelait 'packaging' et que le module python de packaging était installé.

0
Markus