Skip to main content

Custom Lookups

Extend Ryx's query API with your own SQL lookups.

Register a Lookup

import ryx

# Simple SQL template with {col} placeholder
ryx.register_lookup("ilike", "{col} ILIKE ?")

# Usage
Post.objects.filter(title__ilike="%python%")

Decorator Syntax

@ryx.lookup("uuid_prefix")
def uuid_prefix_lookup(field, value):
"""{col}::text LIKE ?"""

The docstring is the SQL template.

No Bind Parameter

If your lookup doesn't need a value:

ryx.register_lookup("even", "{col} % 2 = 0")

# Usage — no value needed
Post.objects.filter(id__even=True)

Override Built-ins

Custom lookups are checked first, so you can override built-ins:

# Use Postgres ILIKE instead of LOWER()...LIKE
ryx.register_lookup("icontains", "{col} ILIKE ?")

Full-Text Search Example

# PostgreSQL full-text search
ryx.register_lookup(
"tsearch",
"to_tsvector({col}) @@ plainto_tsquery(?)"
)

posts = await Post.objects.filter(body__tsearch="async programming")

Available Lookups

# List all registered lookups
lookups = ryx.available_lookups()
print(lookups)
# → ['exact', 'gt', 'gte', 'lt', 'lte', 'contains', 'icontains',
# 'startswith', 'istartswith', 'endswith', 'iendswith',
# 'isnull', 'in', 'range', 'ilike', 'tsearch', 'even']

Next Steps

Sync/Async — Bridge between sync and async code