Skip to main content

Filtering

The .filter() method translates field + value pairs into SQL WHERE clauses.

Basic Syntaxโ€‹

// Exact match
Post::objects().filter("active", true);
Post::objects().filter("author_id", 5i64);

// With a lookup
Post::objects().filter("views__gt", 100i64);

Pattern: field__lookup, value. When no lookup is given, exact is used.

Comparisonโ€‹

Post::objects().filter("views__gt", 100i64);   // >
Post::objects().filter("views__gte", 100i64); // >=
Post::objects().filter("views__lt", 50i64); // <
Post::objects().filter("views__lte", 50i64); // <=

String Lookupsโ€‹

Post::objects().filter("title__contains", "Python");    // LIKE '%Python%'
Post::objects().filter("title__startswith", "How"); // LIKE 'How%'
Post::objects().filter("title__endswith", "guide"); // LIKE '%guide'

Null Checksโ€‹

Post::objects().filter("body__isnull", true);   // IS NULL
Post::objects().filter("body__isnull", false); // IS NOT NULL

Membership & Rangeโ€‹

// IN clause
Post::objects().filter("status__in", vec!["draft", "published"]);

// BETWEEN
Post::objects().filter("views__range", (100i64, 1000i64));

Multiple Filtersโ€‹

Multiple .filter() calls are AND-ed together:

Post::objects()
.filter("active", true)
.filter("views__gt", 100i64)
.filter("title__contains", "Rust");

Excluding (NOT)โ€‹

Use Q::not():

Post::objects().filter(Q::not("status", "draft"));

Post::objects()
.filter("active", true)
.filter(Q::not("title__startswith", "Draft"));

Date Transformsโ€‹

Post::objects().filter("created_at__year", 2024i64);
Post::objects().filter("created_at__month", 5i64);
Post::objects().filter("created_at__day", 15i64);

These work with all comparison lookups: created_at__year__gte=2024.

Custom SQLโ€‹

Post::objects()
.sql_filter("\"title\" ILIKE '%python%'");

Lookup Referenceโ€‹

LookupSQLExample
exactcol = ?.filter("title", "Hello")
gtcol > ?.filter("views__gt", 100)
gtecol >= ?.filter("views__gte", 100)
ltcol < ?.filter("views__lt", 50)
ltecol <= ?.filter("views__lte", 1000)
containsLIKE '%?%'.filter("title__contains", "Py")
startswithLIKE '?%'.filter("title__startswith", "How")
endswithLIKE '%?'.filter("slug__endswith", "-ryx")
inIN (?, ...).filter("status__in", vec!["a","b"])
isnullIS NULL / IS NOT NULL.filter("body__isnull", true)
rangeBETWEEN ? AND ?.filter("views__range", (100, 1000))

Next Stepsโ€‹