signals.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import os
  2. import time
  3. import warnings
  4. from django.conf import settings
  5. from django.db import connections
  6. from django.dispatch import receiver, Signal
  7. from django.utils import timezone
  8. from django.utils.functional import empty
  9. template_rendered = Signal(providing_args=["template", "context"])
  10. setting_changed = Signal(providing_args=["setting", "value", "enter"])
  11. # Most setting_changed receivers are supposed to be added below,
  12. # except for cases where the receiver is related to a contrib app.
  13. # Settings that may not work well when using 'override_settings' (#19031)
  14. COMPLEX_OVERRIDE_SETTINGS = set(['DATABASES'])
  15. @receiver(setting_changed)
  16. def update_connections_time_zone(**kwargs):
  17. if kwargs['setting'] == 'TIME_ZONE':
  18. # Reset process time zone
  19. if hasattr(time, 'tzset'):
  20. if kwargs['value']:
  21. os.environ['TZ'] = kwargs['value']
  22. else:
  23. os.environ.pop('TZ', None)
  24. time.tzset()
  25. # Reset local time zone cache
  26. timezone._localtime = None
  27. # Reset the database connections' time zone
  28. if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC':
  29. USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE
  30. elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ:
  31. USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value']
  32. else:
  33. # no need to change the database connnections' time zones
  34. return
  35. tz = 'UTC' if USE_TZ else TIME_ZONE
  36. for conn in connections.all():
  37. conn.settings_dict['TIME_ZONE'] = tz
  38. tz_sql = conn.ops.set_time_zone_sql()
  39. if tz_sql:
  40. conn.cursor().execute(tz_sql, [tz])
  41. @receiver(setting_changed)
  42. def clear_context_processors_cache(**kwargs):
  43. if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS':
  44. from django.template import context
  45. context._standard_context_processors = None
  46. @receiver(setting_changed)
  47. def clear_template_loaders_cache(**kwargs):
  48. if kwargs['setting'] == 'TEMPLATE_LOADERS':
  49. from django.template import loader
  50. loader.template_source_loaders = None
  51. @receiver(setting_changed)
  52. def clear_serializers_cache(**kwargs):
  53. if kwargs['setting'] == 'SERIALIZATION_MODULES':
  54. from django.core import serializers
  55. serializers._serializers = {}
  56. @receiver(setting_changed)
  57. def language_changed(**kwargs):
  58. if kwargs['setting'] in ('LOCALE_PATHS', 'LANGUAGE_CODE'):
  59. from django.utils.translation import trans_real
  60. trans_real._default = None
  61. if kwargs['setting'] == 'LOCALE_PATHS':
  62. trans_real._translations = {}
  63. @receiver(setting_changed)
  64. def file_storage_changed(**kwargs):
  65. if kwargs['setting'] in ('MEDIA_ROOT', 'DEFAULT_FILE_STORAGE'):
  66. from django.core.files.storage import default_storage
  67. default_storage._wrapped = empty
  68. @receiver(setting_changed)
  69. def complex_setting_changed(**kwargs):
  70. if kwargs['enter'] and kwargs['setting'] in COMPLEX_OVERRIDE_SETTINGS:
  71. warnings.warn("Overriding setting %s can lead to unexpected behaviour." % kwargs['setting'])