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.

lookups.py 1.9KB

5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from django.db.models import Lookup, Transform
  2. from django.db.models.lookups import Exact
  3. from .search import SearchVector, SearchVectorExact, SearchVectorField
  4. class PostgresSimpleLookup(Lookup):
  5. def as_sql(self, qn, connection):
  6. lhs, lhs_params = self.process_lhs(qn, connection)
  7. rhs, rhs_params = self.process_rhs(qn, connection)
  8. params = lhs_params + rhs_params
  9. return '%s %s %s' % (lhs, self.operator, rhs), params
  10. class DataContains(PostgresSimpleLookup):
  11. lookup_name = 'contains'
  12. operator = '@>'
  13. class ContainedBy(PostgresSimpleLookup):
  14. lookup_name = 'contained_by'
  15. operator = '<@'
  16. class Overlap(PostgresSimpleLookup):
  17. lookup_name = 'overlap'
  18. operator = '&&'
  19. class HasKey(PostgresSimpleLookup):
  20. lookup_name = 'has_key'
  21. operator = '?'
  22. prepare_rhs = False
  23. class HasKeys(PostgresSimpleLookup):
  24. lookup_name = 'has_keys'
  25. operator = '?&'
  26. def get_prep_lookup(self):
  27. return [str(item) for item in self.rhs]
  28. class HasAnyKeys(HasKeys):
  29. lookup_name = 'has_any_keys'
  30. operator = '?|'
  31. class Unaccent(Transform):
  32. bilateral = True
  33. lookup_name = 'unaccent'
  34. function = 'UNACCENT'
  35. class SearchLookup(SearchVectorExact):
  36. lookup_name = 'search'
  37. def process_lhs(self, qn, connection):
  38. if not isinstance(self.lhs.output_field, SearchVectorField):
  39. self.lhs = SearchVector(self.lhs)
  40. lhs, lhs_params = super().process_lhs(qn, connection)
  41. return lhs, lhs_params
  42. class TrigramSimilar(PostgresSimpleLookup):
  43. lookup_name = 'trigram_similar'
  44. operator = '%%'
  45. class JSONExact(Exact):
  46. can_use_none_as_rhs = True
  47. def process_rhs(self, compiler, connection):
  48. result = super().process_rhs(compiler, connection)
  49. # Treat None lookup values as null.
  50. return ("'null'", []) if result == ('%s', [None]) else result