4

I'm working on a webproject and using Django. In my views.py file I want to access the database for which I want to import my models.

Here's my directory structure:

├── project  
│   ├── __init__.py  
│   ├── settings.py  
│   ├── urls.py  
│   └── wsgi.py  
├── app  
│   ├── admin.py  
│   ├── __init__.py  
│   ├── models.py  
│   ├── tests.py  
│   └── views.py  
├── manage.py

In my views.py I'm doing import models, but I'm getting an importError. Although from . import models works.

Why?

But the following works without any error:

├── __init__.py
├── mod1.py
└── mod2.py

mod1.py

import mod2

print(mod2.foo())

mod2.py

def foo():
    return "Hello"
Kartik Anand
  • 4,513
  • 5
  • 41
  • 72

2 Answers2

7

In order to use an absolute import, you need to refer to the full package.sibling combo:

import app.models
from app import models
from app.models import mymodel

However, explicit relative imports are an acceptable alternative to absolute imports:

from . import models
from .models import mymodel

You should really read PEP-8 on imports for a great explanation about importing packages.

rnevius
  • 26,578
  • 10
  • 58
  • 86
5

The problem of import models is that you don't know whether its an absolute import or a relative import. models could a module in python's path, or a package in the current module.

This is quite annoying when a local package has the same name as a python standard library package.

You can do from __future__ import absolute_import which turns off implicit relative imports altogether. It is described, including with this justification about ambiguity, in PEP 328. I believe Python 3000 has implicit relative imports turned off completely.

You still can do relative imports, but you have to do them explicitly, like this:

from . import models

Hence, relative imports from . import models work, whereas absolute imports, import models don't.

Community
  • 1
  • 1
Vaulstein
  • 20,055
  • 8
  • 52
  • 73