autoreload.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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 autoreload_started, file_changed, is_django_path
  7. def get_template_directories():
  8. # Iterate through each template backend and find
  9. # any template_loader that has a 'get_dirs' method.
  10. # Collect the directories, filtering out Django templates.
  11. cwd = Path.cwd()
  12. items = set()
  13. for backend in engines.all():
  14. if not isinstance(backend, DjangoTemplates):
  15. continue
  16. items.update(cwd / to_path(dir) for dir in backend.engine.dirs if dir)
  17. for loader in backend.engine.template_loaders:
  18. if not hasattr(loader, "get_dirs"):
  19. continue
  20. items.update(
  21. cwd / to_path(directory)
  22. for directory in loader.get_dirs()
  23. if directory and not is_django_path(directory)
  24. )
  25. return items
  26. def reset_loaders():
  27. from django.forms.renderers import get_default_renderer
  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. backend = getattr(get_default_renderer(), "engine", None)
  34. if isinstance(backend, DjangoTemplates):
  35. for loader in backend.engine.template_loaders:
  36. loader.reset()
  37. @receiver(autoreload_started, dispatch_uid="template_loaders_watch_changes")
  38. def watch_for_template_changes(sender, **kwargs):
  39. for directory in get_template_directories():
  40. sender.watch_dir(directory, "**/*")
  41. @receiver(file_changed, dispatch_uid="template_loaders_file_changed")
  42. def template_changed(sender, file_path, **kwargs):
  43. if file_path.suffix == ".py":
  44. return
  45. for template_dir in get_template_directories():
  46. if template_dir in file_path.parents:
  47. reset_loaders()
  48. return True