Home > Enterprise >  Why isn't the current directory in sys.path for a django application
Why isn't the current directory in sys.path for a django application

Time:07-25

To my understanding, the sys.path has the current directory (the directory the module is in) as its first index, yet this seems inconsistent with django.

I have a project structure:

In my_file_1.py, printing sys.path gives me: enter image description here

In my_file_2.py, printing sys.path gives me: enter image description here

These two sys.path prints makes sense since that red underline is the directory the modules are in (their respective current directory).

However, in my django app with the following project structure:

enter image description here

When printing sys.path in urls.py, I get:

enter image description here

Which is the root directory of the project, instead of the current directory of urls.py which should be c:\\Users\\5403\\Desktop\\tutorial\\tutorial

Could someone explain this inconsistency and correct me if I have any misconceptions, thanks.

CodePudding user response:

Django modifies the sys.path to contain the project root directory so that things like import mysite.settings should work everywhere in your project.

Refer to django docs here

Also, Python does allow modification of sys.path. From the Python docs

A program is free to modify this list for its own purposes. Only strings and bytes should be added to sys.path; all other data types are ignored during import.

If your objective is to get the directory urls.py is in, you should use the approach django uses in its settings.py file.

BASE_DIR = Path(__file__).resolve().parent.parent

CodePudding user response:

Consider the following example:

code00.py:

#!/usr/bin/env python

import os
import sys
from pprint import pprint as pp

import inner.code01


pp({os.path.abspath(__file__): sys.path[:4]})

code01.py (located in dir called inner, next to code00.py):

#!/usr/bin/env python

import os
import sys
from pprint import pprint as pp


pp({os.path.abspath(__file__): sys.path[:4]})

Output:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q073104391]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> tree /a /f
Folder PATH listing for volume SSD0-WORK
Volume serial number is AE9E-72AC
E:.
|   code00.py
|
\---inner
    |   code01.py
    |
    \---__pycache__
            code01.cpython-39.pyc


[prompt]>
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" inner/code01.py
{'e:\\Work\\Dev\\StackOverflow\\q073104391\\inner\\code01.py': ['e:\\Work\\Dev\\StackOverflow\\q073104391\\inner',
                                                                'e:\\Work\\Dev\\Utils\\current',
                                                                'e:\\Work\\Dev\\Utils',
                                                                'c:\\Install\\pc064\\Python\\Python\\03.09\\python39.zip']}

[prompt]>
[prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" ./code00.py
{'e:\\Work\\Dev\\StackOverflow\\q073104391\\inner\\code01.py': ['e:\\Work\\Dev\\StackOverflow\\q073104391',
                                                                'e:\\Work\\Dev\\Utils\\current',
                                                                'e:\\Work\\Dev\\Utils',
                                                                'c:\\Install\\pc064\\Python\\Python\\03.09\\python39.zip']}
{'e:\\Work\\Dev\\StackOverflow\\q073104391\\code00.py': ['e:\\Work\\Dev\\StackOverflow\\q073104391',
                                                         'e:\\Work\\Dev\\Utils\\current',
                                                         'e:\\Work\\Dev\\Utils',
                                                         'c:\\Install\\pc064\\Python\\Python\\03.09\\python39.zip']}

What happens is that when running a module directly, Python adds its location (as 1st entry) in [Python.Docs]: sys.path (default behavior). When importing one, this (naturally) doesn't happen.

Same thing happens in your case, when you run modules directly, their location is in sys.path (you could test that by launching urls.py).

So, there's no inconsistency on Django (Python) side, but on the way you are dealing with modules.

So, if you really want urls.py in sys.path (although if this was truly necessary it would be done by Django automatically), add it either:

  • Manually

  • From Django's config file

  • Related