1

I have a Django project (Python 2.7.15) with the following structure:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py
    polls/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py
        utils.py
    utils/
        __init__.py
        filters.py

In my utils/filters.py file I have a class MyFilter. From polls/admin.py, however, when I try to run from utils.filters import MyFilter, I get ImportError: No module named filters. How can I import my custom filter inside the polls app without renaming the polls/utils.py module or the utils package?

NOTE: This it's not a circular import problem. This happens even if I don't import anything from utils/filters.py. It's a name conflict between utils/ and polls/utils.py. Python tries to find filters.MyFilter inside polls/utils.py and it doesn't find it so it throws the error. I just want to figure out a way to bypass this conflict and force python to look for filters.MyFilter inside the utils/ package in the project root.

Ariel
  • 3,383
  • 4
  • 43
  • 58
  • Possible duplicate of [Simple cross import in python](https://stackoverflow.com/questions/17226016/simple-cross-import-in-python) – Brown Bear Sep 04 '18 at 14:38
  • @BearBrown it's not a circular import problem. This happens even if I don't import anything from `utils/filters.py`. It's a name conflict between `utils/` and `polls/utils.py`. Python tries to find `filters.MyFilter` inside `polls/utils.py` and it doesn't so it throws the error. I just want to figure out a way to bypass this conflict and force python to look for `filters.MyFilter` inside the `utils/` package in the project root. – Ariel Sep 04 '18 at 14:43

1 Answers1

2

In Python 2, import utils is ambiguous because it can be a relative or an absolute import.

If you enable the Python 3 behaviour by adding the following import to the top of your module,

from __future__ import absolute_import

then from utils.filters import MyFilter will be treated as an absolute import and will work.

Once you have added the future import, you would need to use an explicit relative import import .utils if you wanted to import polls/utils.py from polls/admin.py.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • That did it. I forgot to mention I was using Python 2, my bad. I updated the body of the question to also mention that. Thanks! – Ariel Sep 04 '18 at 15:07
  • Weirdly enough, this caused errors elsewhere in the project where there were relative imports (with dots) `RuntimeError: Model class 'foo.models.Bar' doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.`. Changing `from .models import Bar` to `from myapp.models import Bar` fixed the issue. This seems totally mysterious to me I don't understand how it is possible, but I guess that's a topic for another question. – Ariel Sep 05 '18 at 08:15
  • Yes, it sounds like that belongs on another question, and would require more information to explain what was going on. – Alasdair Sep 05 '18 at 09:08