You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from psycopg2.extras import (
  2. DateRange, DateTimeRange, DateTimeTZRange, NumericRange,
  3. )
  4. from django.apps import AppConfig
  5. from django.db import connections
  6. from django.db.backends.signals import connection_created
  7. from django.db.migrations.writer import MigrationWriter
  8. from django.db.models import CharField, TextField
  9. from django.test.signals import setting_changed
  10. from django.utils.translation import gettext_lazy as _
  11. from .lookups import SearchLookup, TrigramSimilar, Unaccent
  12. from .serializers import RangeSerializer
  13. from .signals import register_type_handlers
  14. RANGE_TYPES = (DateRange, DateTimeRange, DateTimeTZRange, NumericRange)
  15. def uninstall_if_needed(setting, value, enter, **kwargs):
  16. """
  17. Undo the effects of PostgresConfig.ready() when django.contrib.postgres
  18. is "uninstalled" by override_settings().
  19. """
  20. if not enter and setting == 'INSTALLED_APPS' and 'django.contrib.postgres' not in set(value):
  21. connection_created.disconnect(register_type_handlers)
  22. CharField._unregister_lookup(Unaccent)
  23. TextField._unregister_lookup(Unaccent)
  24. CharField._unregister_lookup(SearchLookup)
  25. TextField._unregister_lookup(SearchLookup)
  26. CharField._unregister_lookup(TrigramSimilar)
  27. TextField._unregister_lookup(TrigramSimilar)
  28. # Disconnect this receiver until the next time this app is installed
  29. # and ready() connects it again to prevent unnecessary processing on
  30. # each setting change.
  31. setting_changed.disconnect(uninstall_if_needed)
  32. MigrationWriter.unregister_serializer(RANGE_TYPES)
  33. class PostgresConfig(AppConfig):
  34. name = 'django.contrib.postgres'
  35. verbose_name = _('PostgreSQL extensions')
  36. def ready(self):
  37. setting_changed.connect(uninstall_if_needed)
  38. # Connections may already exist before we are called.
  39. for conn in connections.all():
  40. if conn.vendor == 'postgresql':
  41. conn.introspection.data_types_reverse.update({
  42. 3802: 'django.contrib.postgres.fields.JSONField',
  43. 3904: 'django.contrib.postgres.fields.IntegerRangeField',
  44. 3906: 'django.contrib.postgres.fields.DecimalRangeField',
  45. 3910: 'django.contrib.postgres.fields.DateTimeRangeField',
  46. 3912: 'django.contrib.postgres.fields.DateRangeField',
  47. 3926: 'django.contrib.postgres.fields.BigIntegerRangeField',
  48. })
  49. if conn.connection is not None:
  50. register_type_handlers(conn)
  51. connection_created.connect(register_type_handlers)
  52. CharField.register_lookup(Unaccent)
  53. TextField.register_lookup(Unaccent)
  54. CharField.register_lookup(SearchLookup)
  55. TextField.register_lookup(SearchLookup)
  56. CharField.register_lookup(TrigramSimilar)
  57. TextField.register_lookup(TrigramSimilar)
  58. MigrationWriter.register_serializer(RANGE_TYPES, RangeSerializer)