0

I've been following the Django Docs topic Organizing models in a package and get everything working. Then as I move to a new section, and change a model or add new models, when I go to make migrations I keep hitting an ImportError when that model has a foreign key to my Users model.

I'm using a project based on django-cookie-cutter and have added new apps, as well as refactored the models.py to a directory/package.

Here's the terminal output:

(iqport) C:\dev\iqdev\iqport>python manage.py makemigrations
Loading : C:\dev\iqdev\iqport\.env
The .env file has been loaded. See base.py for more information
Traceback (most recent call last):
  File "manage.py", line 29, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Env\iqport\lib\site-packages\django\core\management\__init__.py", line 363, in execute_from_command_line
    utility.execute()
  File "C:\Env\iqport\lib\site-packages\django\core\management\__init__.py", line 337, in execute
    django.setup()
  File "C:\Env\iqport\lib\site-packages\django\__init__.py", line 27, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Env\iqport\lib\site-packages\django\apps\registry.py", line 108, in populate
    app_config.import_models()
  File "C:\Env\iqport\lib\site-packages\django\apps\config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "C:\Program Files\Python36\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 978, in _gcd_import
  File "<frozen importlib._bootstrap>", line 961, in _find_and_load
  File "<frozen importlib._bootstrap>", line 950, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
  File "C:\dev\iqdev\iqport\iqport\users\models.py", line 8, in <module>
    from iqport.core.models import Client
  File "C:\dev\iqdev\iqport\iqport\core\models\__init__.py", line 3, in <module>
    from .staffing import TeamMember
  File "C:\dev\iqdev\iqport\iqport\core\models\staffing.py", line 5, in <module>
    from iqport.users.models import User
ImportError: cannot import name 'User'

Here is the new model I'm trying to generate migrations on:

from django.db import models
from django.utils import timezone
from simple_history.models import HistoricalRecords

from iqport.users.models import User
from iqport.core.models.core_config import StaffRoles, Client


class TeamMember(models.Model):
    staff = models.ForeignKey(User)
    client = models.ForeignKey(Client)
    role = models.ForeignKey(StaffRoles)
    valid_from = models.DateField(auto_now=True)
    valid_to = models.DateField(null=True, blank=True)
    history = HistoricalRecords()

On another project I had the same issue and only got past it after killing all my migrations and starting fresh. It doesn't make any sense to have to do this, and I can't see why it's complaining about importing the User model. In PyCharm, the model code is validated and there are no errors shown on that import, only when running the make migrations.

Does anyone have some advice to overcome this, aside from advocating not to split the models? TIA.

EDIT: Commenting out the import:

from iqport.core.models import Client

in my Users model makes this go away.

wedward
  • 363
  • 2
  • 11
  • Are you importing any models from the `TeamMember` file into your `iqport.users.models` file? It looks like you're experiencing a circular import. – Cory Madden Aug 09 '17 at 02:02
  • No I checked that but I am importing the "Client" model (different file but in same app), and I checked that Client does not refer to either model. The TeamMember does have FK to Client though. Could that be the circular reference perhaps? – wedward Aug 09 '17 at 02:08
  • @wedward you mentioned that you apply Organizing models in a package instructions in you project, i guess you may put you models file into a directory named models, if that's right you need to import model like this: from app.models.specificModelFileName import User, list out the file directory may be helpful for us to spot the issue – wllbll Aug 09 '17 at 02:18

1 Answers1

0

circular importAs I mentioned in the comments, it's a circular import error.

 File "C:\dev\iqdev\iqport\iqport\users\models.py", line 8, in <module>
    from iqport.core.models import Client
  File "C:\dev\iqdev\iqport\iqport\core\models\__init__.py", line 3, in <module>
    from .staffing import TeamMember
  File "C:\dev\iqdev\iqport\iqport\core\models\staffing.py", line 5, in <module>
    from iqport.users.models import User
ImportError: cannot import name 'User'

You can try doing a higher level import like:

from iqport.users.models as user_models

and create your foreign key like so:

staff = models.ForeignKey(user_models.User)

Killing your migrations isn't going to help this problem.

Cory Madden
  • 5,026
  • 24
  • 37