autoreload.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. from pathlib import Path
  2. from django.dispatch import receiver
  3. from django.template import engines
  4. from django.template.backends.django import DjangoTemplates
  5. from django.utils._os import to_path
  6. from django.utils.autoreload import (
  7. autoreload_started, file_changed, is_django_path,
  8. )
  9. def get_template_directories():
  10. # Iterate through each template backend and find
  11. # any template_loader that has a 'get_dirs' method.
  12. # Collect the directories, filtering out Django templates.
  13. items = set()
  14. for backend in engines.all():
  15. if not isinstance(backend, DjangoTemplates):
  16. continue
  17. items.update(Path.cwd() / to_path(dir) for dir in backend.engine.dirs if dir)
  18. for loader in backend.engine.template_loaders:
  19. if not hasattr(loader, 'get_dirs'):
  20. continue
  21. items.update(
  22. Path.cwd() / to_path(directory)
  23. for directory in loader.get_dirs()
  24. if directory and not is_django_path(directory)
  25. )
  26. return items
  27. def reset_loaders():
  28. for backend in engines.all():
  29. if not isinstance(backend, DjangoTemplates):
  30. continue
  31. for loader in backend.engine.template_loaders:
  32. loader.reset()
  33. @receiver(autoreload_started, dispatch_uid='template_loaders_watch_changes')
  34. def watch_for_template_changes(sender, **kwargs):
  35. for directory in get_template_directories():
  36. sender.watch_dir(directory, '**/*')
  37. @receiver(file_changed, dispatch_uid='template_loaders_file_changed')
  38. def template_changed(sender, file_path, **kwargs):
  39. for template_dir in get_template_directories():
  40. if template_dir in file_path.parents:
  41. reset_loaders()
  42. return True