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