1

I have a question regarding the import//from statement in python.

In my views.py file (Project/App/views.py) I have this line:

from django.views.generic import TemplateView, ListView

Why do I have to include 'django' in that line? Why is it not enough to specify which directory (views) that the generic file is located in? This is what I have done in many of my previous python-only scripts - an example being:

from random import foo

as well as in my current django url.py file. There, I have:

from app.views import view

Why don't I have to specify that further, like with the first example where 'django' is included in the path-specification? How come I don't have to write it like this:

from project.app.views import view

Thank you!

Harald Nordgren
  • 11,693
  • 6
  • 41
  • 65
William Karlsson
  • 219
  • 2
  • 16

2 Answers2

1

Welcome to the wild world of Python's import system!

To expand on freude's answer a little bit, you've ran into one of the most consistently confusing portions of the Python language: relative vs absolute imports. While the import examples that you gave are syntactically fine, they hide some of the complexity what's going on behind the scenes. When you run:

from django.views.generic import TemplateView, ListView

Python searches through the PYTHONPATH (which you can see with something like print(sys.path)) for a package or module named django. It end up finding one somewhere among your installed libraries. Similarly, when you run:

from project.app.views import view 

It searches those same paths, but instead finds the project package in the directory that the Python interpreter is currently executing in. However, if you had installed a library named project, how would it know which one you actually meant? This is generally solved by using absolute imports and by being explicit if you intend to use relative imports like this. If you wanted to be more precise in your example, you would specify that you wanted to import it relative to the current module by using a . - like so:

from .project.app.views import view    

You can even see this in action in an example in the django tutorial.

See this classic answer on the subject for more detailed information.

jtimmons
  • 376
  • 3
  • 7
0

A python script sees certain paths pointing to the the global default location like site-packages or dist-packages (you may find those directories in the python directory tree and random and django are located in one of them) or specified by the environment variable PYTHONPATH. Usually, PYTHONPATH includes your project directory (actually you may add there whatever directory you want). Your example suggests that the packages django as well as apps and random are located in those paths while project is not there. In python a package is represented by a directory containing __init__.py file as well as some other files representing modules. Now you may import modules from packages in those locations using relative paths like you have shown in your examples.

freude
  • 3,632
  • 3
  • 32
  • 51