django/django · error · NotSupportedError
This backend does not support expressions for specifying dis
Error message
This backend does not support expressions for specifying distance in the dwithin lookup.
What it means
Raised as NotSupportedError by DWithinLookup.process_distance when the active database backend does not expose supports_dwithin_distance_expr and the supplied distance argument is an expression (has resolve_expression) that is not a Distance instance. SQLite/SpatiaLite and some older backends cannot compile an arbitrary expression into the third argument of ST_DWithin.
Source
Thrown at django/contrib/gis/db/models/lookups.py:345
self.lhs.output_field, self.rhs_params, self.lookup_name
),
)
)
@BaseSpatialField.register_lookup
class DWithinLookup(DistanceLookupBase):
lookup_name = "dwithin"
sql_template = "%(func)s(%(lhs)s, %(rhs)s, %(value)s)"
def process_distance(self, compiler, connection):
dist_param = self.rhs_params[0]
if (
not connection.features.supports_dwithin_distance_expr
and hasattr(dist_param, "resolve_expression")
and not isinstance(dist_param, Distance)
):
raise NotSupportedError(
"This backend does not support expressions for specifying "
"distance in the dwithin lookup."
)
return super().process_distance(compiler, connection)
def process_rhs(self, compiler, connection):
dist_sql, dist_params = self.process_distance(compiler, connection)
self.template_params["value"] = dist_sql
rhs_sql, params = super().process_rhs(compiler, connection)
return rhs_sql, (*params, *dist_params)
class DistanceLookupFromFunction(DistanceLookupBase):
def as_sql(self, compiler, connection):
spheroid = (
len(self.rhs_params) == 2 and self.rhs_params[-1] == "spheroid"
) or None
distance_expr = connection.ops.distance_expr_for_lookup(View on GitHub (pinned to ae25a40be0)
Solutions
- Pass a concrete Distance(...) or numeric literal instead of an expression.
- If you need per-row distances, switch to a backend with supports_dwithin_distance_expr=True (PostGIS).
- Precompute the distance value in Python and pass it as D(m=value).
Example fix
// before
QS.filter(geom__dwithin=(pt, F('radius'))) # on SpatiaLite
// after
QS.filter(geom__dwithin=(pt, D(m=obj.radius))) Defensive patterns
Strategy: fallback
Validate before calling
from django.db.models import Expression
from django.contrib.gis.measure import Distance
def coerce_dwithin_distance(backend_features, dist):
if not backend_features.supports_dwithin_distance_expr and isinstance(dist, Expression) and not isinstance(dist, Distance):
raise NotSupportedError('Resolve expression to a Distance before dwithin on this backend')
return dist Type guard
def is_dwithin_safe(backend_features, dist):
return backend_features.supports_dwithin_distance_expr or isinstance(dist, Distance) or not hasattr(dist, 'resolve_expression') Try / catch
from django.db import NotSupportedError
try:
QS.filter(geom__dwithin=(pt, expr))
except NotSupportedError as e:
if 'dwithin' in str(e):
QS.filter(geom__dwithin=(pt, D(m=resolved_value))) Prevention
- Check connection.features.supports_dwithin_distance_expr before passing expressions.
- Keep a PostGIS target for production if you need expression-based distance queries.
When it happens
Trigger: On SpatiaLite, Model.objects.filter(geom__dwithin=(pt, F('radius'))) or an annotated expression. The features.supports_dwithin_distance_expr flag is False, dist_param is an Expression, and it is not a Distance, so lookups.py:345 raises.
Common situations: Developing locally on SQLite/SpatiaLite and deploying to PostGIS; passing an F() object or aggregate where a Distance measurement is expected.
Related errors
- Only numeric values of degree units are allowed on geographi
- Distance operations not available on this spatial backend.
- Only numeric values of degree units are allowed on geographi
- SpatiaLite requires SQLite to be configured to allow extensi
- Unable to load the SpatiaLite library extension as specified
AI-assisted analysis of django/django@ae25a40be0 (2026-08-06).
Data as JSON: /api/errors/078743fb8cf8f300.
Report an issue: GitHub.