django.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 import misc
  13. from PyInstaller.utils.hooks import eval_script
  14. __all__ = ['django_dottedstring_imports', 'django_find_root_dir']
  15. def django_dottedstring_imports(django_root_dir):
  16. """
  17. Get all the necessary Django modules specified in settings.py.
  18. In the settings.py the modules are specified in several variables as strings.
  19. """
  20. pths = []
  21. # Extend PYTHONPATH with parent dir of django_root_dir.
  22. pths.append(misc.get_path_to_toplevel_modules(django_root_dir))
  23. # Extend PYTHONPATH with django_root_dir.
  24. # Often, Django users do not specify absolute imports in the settings module.
  25. pths.append(django_root_dir)
  26. default_settings_module = os.path.basename(django_root_dir) + '.settings'
  27. settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', default_settings_module)
  28. env = {'DJANGO_SETTINGS_MODULE': settings_module, 'PYTHONPATH': os.pathsep.join(pths)}
  29. ret = eval_script('django_import_finder.py', env=env)
  30. return ret
  31. def django_find_root_dir():
  32. """
  33. Return path to directory (top-level Python package) that contains main django files. Return None if no directory
  34. was detected.
  35. Main Django project directory contain files like '__init__.py', 'settings.py' and 'url.py'.
  36. In Django 1.4+ the script 'manage.py' is not in the directory with 'settings.py' but usually one level up. We
  37. need to detect this special case too.
  38. """
  39. # 'PyInstaller.config' cannot be imported as other top-level modules.
  40. from PyInstaller.config import CONF
  41. # Get the directory with manage.py. Manage.py is supplied to PyInstaller as the first main executable script.
  42. manage_py = CONF['main_script']
  43. manage_dir = os.path.dirname(os.path.abspath(manage_py))
  44. # Get the Django root directory. The directory that contains settings.py and url.py. It could be the directory
  45. # containing manage.py or any of its subdirectories.
  46. settings_dir = None
  47. files = set(os.listdir(manage_dir))
  48. if ('settings.py' in files or 'settings' in files) and 'urls.py' in files:
  49. settings_dir = manage_dir
  50. else:
  51. for f in files:
  52. if os.path.isdir(os.path.join(manage_dir, f)):
  53. subfiles = os.listdir(os.path.join(manage_dir, f))
  54. # Subdirectory contains critical files.
  55. if ('settings.py' in subfiles or 'settings' in subfiles) and 'urls.py' in subfiles:
  56. settings_dir = os.path.join(manage_dir, f)
  57. break # Find the first directory.
  58. return settings_dir