django.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. # ----------------------------------------------------------------------------
  2. # Copyright (c) 2005-2021, PyInstaller Development Team.
  3. #
  4. # Distributed under the terms of the GNU General Public License (version 2
  5. # or later) with exception for distributing the bootloader.
  6. #
  7. # The full license is in the file COPYING.txt, distributed with this software.
  8. #
  9. # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
  10. # ----------------------------------------------------------------------------
  11. import os
  12. from PyInstaller.utils.hooks import eval_script
  13. from PyInstaller.utils import misc
  14. __all__ = [
  15. 'django_dottedstring_imports', 'django_find_root_dir'
  16. ]
  17. def django_dottedstring_imports(django_root_dir):
  18. """
  19. Get all the necessary Django modules specified in settings.py.
  20. In the settings.py the modules are specified in several variables
  21. as strings.
  22. """
  23. pths = []
  24. # Extend PYTHONPATH with parent dir of django_root_dir.
  25. pths.append(misc.get_path_to_toplevel_modules(django_root_dir))
  26. # Extend PYTHONPATH with django_root_dir.
  27. # Often, Django users do not specify absolute imports in the settings
  28. # module.
  29. pths.append(django_root_dir)
  30. default_settings_module = os.path.basename(django_root_dir) + '.settings'
  31. settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', default_settings_module)
  32. env = {'DJANGO_SETTINGS_MODULE': settings_module,
  33. 'PYTHONPATH': os.pathsep.join(pths)}
  34. ret = eval_script('django_import_finder.py', env=env)
  35. return ret
  36. def django_find_root_dir():
  37. """
  38. Return path to directory (top-level Python package) that contains main django
  39. files. Return None if no directory was detected.
  40. Main Django project directory contain files like '__init__.py', 'settings.py'
  41. and 'url.py'.
  42. In Django 1.4+ the script 'manage.py' is not in the directory with 'settings.py'
  43. but usually one level up. We need to detect this special case too.
  44. """
  45. # 'PyInstaller.config' cannot be imported as other top-level modules.
  46. from PyInstaller.config import CONF
  47. # Get the directory with manage.py. Manage.py is supplied to PyInstaller as the
  48. # first main executable script.
  49. manage_py = CONF['main_script']
  50. manage_dir = os.path.dirname(os.path.abspath(manage_py))
  51. # Get the Django root directory. The directory that contains settings.py and url.py.
  52. # It could be the directory containing manage.py or any of its subdirectories.
  53. settings_dir = None
  54. files = set(os.listdir(manage_dir))
  55. if ('settings.py' in files or 'settings' in files) and 'urls.py' in files:
  56. settings_dir = manage_dir
  57. else:
  58. for f in files:
  59. if os.path.isdir(os.path.join(manage_dir, f)):
  60. subfiles = os.listdir(os.path.join(manage_dir, f))
  61. # Subdirectory contains critical files.
  62. if ('settings.py' in subfiles or 'settings' in subfiles) and 'urls.py' in subfiles:
  63. settings_dir = os.path.join(manage_dir, f)
  64. break # Find the first directory.
  65. return settings_dir