lookups.py 1.0 KB

12345678910111213141516171819202122232425262728293031323334
  1. from django.db.models import lookups
  2. from django.db.models.fields import Field, related_lookups
  3. from django.db.models.fields.related import ForeignObject
  4. class InValuesLookupMixin:
  5. """Performs a `lhs IN VALUES ((a), (b), (c))` lookup.
  6. This can be significantly faster then a normal `IN (a, b, c)`. The
  7. latter sometimes causes the Postgres query planner do a sequential
  8. scan.
  9. """
  10. def as_sql(self, compiler, connection):
  11. if not self.rhs_is_direct_value():
  12. return super().as_sql(compiler, connection)
  13. lhs, lhs_params = self.process_lhs(compiler, connection)
  14. _, rhs_params = self.process_rhs(compiler, connection)
  15. rhs = ",".join([f"(%s)" for _ in rhs_params]) # noqa: F541
  16. return f"{lhs} IN (VALUES {rhs})", lhs_params + list(rhs_params)
  17. @Field.register_lookup
  18. class InValuesLookup(InValuesLookupMixin, lookups.In):
  19. lookup_name = "invalues"
  20. @ForeignObject.register_lookup
  21. class InValuesRelatedLookup(InValuesLookupMixin, related_lookups.RelatedIn):
  22. lookup_name = "invalues"