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:
In my_file_2.py
, printing sys.path
gives me:
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:
When printing sys.path in urls.py, I get:
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