hook-django.py 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #-----------------------------------------------------------------------------
  2. # Copyright (c) 2005-2023, 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. # Tested with django 2.2
  12. import glob
  13. import os
  14. from PyInstaller import log as logging
  15. from PyInstaller.utils import hooks
  16. from PyInstaller.utils.hooks import django
  17. logger = logging.getLogger(__name__)
  18. # Collect everything. Some submodules of django are not importable without considerable external setup. Ignore the
  19. # errors they raise.
  20. datas, binaries, hiddenimports = hooks.collect_all('django', on_error="ignore")
  21. root_dir = django.django_find_root_dir()
  22. if root_dir:
  23. logger.info('Django root directory %s', root_dir)
  24. # Include imports from the mysite.settings.py module.
  25. settings_py_imports = django.django_dottedstring_imports(root_dir)
  26. # Include all submodules of all imports detected in mysite.settings.py.
  27. for submod in settings_py_imports:
  28. hiddenimports.append(submod)
  29. hiddenimports += hooks.collect_submodules(submod)
  30. # Include main django modules - settings.py, urls.py, wsgi.py. Without them the django server won't run.
  31. package_name = os.path.basename(root_dir)
  32. default_settings_module = f'{package_name}.settings'
  33. settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', default_settings_module)
  34. hiddenimports += [
  35. # TODO: consider including 'mysite.settings.py' in source code as a data files,
  36. # since users might need to edit this file.
  37. settings_module,
  38. package_name + '.urls',
  39. package_name + '.wsgi',
  40. ]
  41. # Django hiddenimports from the standard Python library.
  42. hiddenimports += [
  43. 'http.cookies',
  44. 'html.parser',
  45. ]
  46. # Bundle django DB schema migration scripts as data files. They are necessary for some commands.
  47. logger.info('Collecting Django migration scripts.')
  48. migration_modules = [
  49. 'django.conf.app_template.migrations',
  50. 'django.contrib.admin.migrations',
  51. 'django.contrib.auth.migrations',
  52. 'django.contrib.contenttypes.migrations',
  53. 'django.contrib.flatpages.migrations',
  54. 'django.contrib.redirects.migrations',
  55. 'django.contrib.sessions.migrations',
  56. 'django.contrib.sites.migrations',
  57. ]
  58. # Include migration scripts of Django-based apps too.
  59. installed_apps = hooks.get_module_attribute(settings_module, 'INSTALLED_APPS')
  60. migration_modules.extend(set(app + '.migrations' for app in installed_apps))
  61. # Copy migration files.
  62. for mod in migration_modules:
  63. mod_name, bundle_name = mod.split('.', 1)
  64. mod_dir = os.path.dirname(hooks.get_module_file_attribute(mod_name))
  65. bundle_dir = bundle_name.replace('.', os.sep)
  66. pattern = os.path.join(mod_dir, bundle_dir, '*.py')
  67. files = glob.glob(pattern)
  68. for f in files:
  69. datas.append((f, os.path.join(mod_name, bundle_dir)))
  70. # Include data files from your Django project found in your django root package.
  71. datas += hooks.collect_data_files(package_name)
  72. # Include database file if using sqlite. The sqlite database is usually next to the manage.py script.
  73. root_dir_parent = os.path.dirname(root_dir)
  74. # TODO Add more patterns if necessary.
  75. _patterns = ['*.db', 'db.*']
  76. for p in _patterns:
  77. files = glob.glob(os.path.join(root_dir_parent, p))
  78. for f in files:
  79. # Place those files next to the executable.
  80. datas.append((f, '.'))
  81. else:
  82. logger.warning('No django root directory could be found!')