How does django manage.py put a project package on sys.path

I read the django doc and some SO posts to know the differences between manage.py and django-admin.py.

They all say:

manage.py is automatically created in each Django project. manage.py is a thin wrapper around django-admin.py that takes care of two things for you before delegating to django-admin.py:

  • It puts your project's package on sys.path.
  • It sets the DJANGO_SETTINGS_MODULE environment variable so that it points to your project's settings.py file.
  • So I checked the scource code of these 2 files(latest version, so it the doc).

    Then I am confused. manage.py does the second thing: sets the DJANGO_SETTINGS_MODULE environment variable. Besides that, I really can not find any differences between these 2 scripts.

    [django-admin.py]

    #!/usr/bin/env python
    from django.core import management
    
    if __name__ == "__main__":
        management.execute_from_command_line()
    

    [manage.py]

    #!/usr/bin/env python
    import os
    import sys
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
    
        from django.core.management import execute_from_command_line
    
        execute_from_command_line(sys.argv)
    

    Why? Is the django documentation out of date? Or I missed something here? And where is the code that puts the project's package on sys.path?


    The sys.path is updated here using handle_default_options(options) statement located here. The execution path is as follows:

  • execute_from_command_line(argv) (your manage.py )
  • utility.execute() here
  • handle_default_options(options) here
  • The same method is used by Command class used as base class for management commands.


    From what I can see it's not ./manage.py who "puts your project's package on sys.path."

    The doc says:

    sys.path is initialized from these locations:

  • The directory containing the input script (or the current directory when no file is specified).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • The installation-dependent default.
  • The installation-dependent default must be what site.py adds. But it can be disabled with -S switch. Now then when I run this script ( 1.py ):

    import sys
    print(sys.path)
    

    I get:

    $ python -S ../1.py   # to show that it's not current directory that is added
    ['/path/to/the/script/directory', '/usr/lib/python35.zip', '/usr/lib/python3.5/', 
    '/usr/lib/python3.5/plat-linux', '/usr/lib/python3.5/lib-dynload']
    

    So, when you run django-admin , /path/to/env/bin/django-admin will be the first on the sys.path . And when ./manage.py , /path/to/project .

    As such, one can probably say that ./manage.py "puts your project's package on sys.path," but indirectly, by being at the root of your project.

    链接地址: http://www.djcxy.com/p/59782.html

    上一篇: DJango manage.py不运行syncdb命令并打开代码编辑器

    下一篇: django manage.py如何在sys.path中放置一个工程包