{"record":{"id":"8b3a19324843381a","repo":"django/django","slug":"only-numeric-values-of-degree-units-are-allowed-on-8b3a19","errorCode":null,"errorMessage":"Only numeric values of degree units are allowed on geographic DWithin queries.","messagePattern":"Only numeric values of degree units are allowed on geographic DWithin queries\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"django/contrib/gis/db/backends/spatialite/operations.py","lineNumber":140,"sourceCode":"    def geo_db_type(self, f):\n        \"\"\"\n        Return None because geometry columns are added via the\n        `AddGeometryColumn` stored procedure on SpatiaLite.\n        \"\"\"\n        return None\n\n    def get_distance(self, f, value, lookup_type):\n        \"\"\"\n        Return the distance parameters for the given geometry field,\n        lookup value, and lookup type.\n        \"\"\"\n        if not value:\n            return []\n        value = value[0]\n        if isinstance(value, Distance):\n            if f.geodetic(self.connection):\n                if lookup_type == \"dwithin\":\n                    raise ValueError(\n                        \"Only numeric values of degree units are allowed on \"\n                        \"geographic DWithin queries.\"\n                    )\n                dist_param = value.m\n            else:\n                dist_param = getattr(\n                    value, Distance.unit_attname(f.units_name(self.connection))\n                )\n        else:\n            dist_param = value\n        return [dist_param]\n\n    def _get_spatialite_func(self, func):\n        \"\"\"\n        Helper routine for calling SpatiaLite functions and returning\n        their result.\n        Any error occurring in this method should be handled by the caller.\n        \"\"\"","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/django/django/blob/ae25a40be07e8a749edf526df37c93e59d4a22c9/django/contrib/gis/db/backends/spatialite/operations.py#L122-L158","documentation":"ValueError raised in get_distance (operations.py:140) when a Distance object is supplied to a dwithin lookup on a geodetic (lat/lon) SpatiaLite field. SpatiaLite's PtDistWithin on geographic data needs a plain degree value, not a Distance with metre/foot units.","triggerScenarios":"Calling Model.objects.filter(geom__dwithin=(point, D(km=5))) where geom has srid=4326 (geodetic) on the spatialite backend; the D(...) shortcut wraps the value as a Distance instance.","commonSituations":"Reusing the same query across PostGIS (geography) and SpatiaLite; copy-pasting a metre-based distance filter from a PostGIS tutorial into a SpatiaLite project; assuming D(m=...) works everywhere.","solutions":["Pass a numeric degree value for geodetic dwithin: filter(geom__dwithin=(point, 0.05)) where 0.05 ≈ degrees.","If you really need metre semantics, use a projected (non-geodetic) SRID for the field so Distance is accepted.","On PostGIS, declare the field with geography=True to keep D(m=...) working.","Convert metres to degrees at the call site (approximate: degrees = metres / 111320 for rough latitude)."],"exampleFix":"# before: distance object on geodetic spatialite\nqs = Shop.objects.filter(geom__dwithin=(pt, D(km=5)))\n# after: plain degree value\nqs = Shop.objects.filter(geom__dwithin=(pt, 0.045))  # ~5 km","handlingStrategy":"type-guard","validationCode":"from django.contrib.gis.measure import Distance\nfrom django.contrib.gis.geos import GEOSGeometry\n\ndef dwithin_value(field, point, dist):\n    if field.geodetic and isinstance(dist, Distance):\n        raise ValueError('geodetic dwithin needs a numeric degree value, not Distance')\n    return (point, dist)","typeGuard":"from django.contrib.gis.measure import Distance\n\ndef is_distance_obj(v) -> bool:\n    return isinstance(v, Distance)","tryCatchPattern":"try:\n    qs = Model.objects.filter(geom__dwithin=(pt, value))\nexcept ValueError:\n    # value was a Distance on a geodetic field; fall back to a degree value\n    qs = Model.objects.filter(geom__dwithin=(pt, metres_to_degrees(value)))","preventionTips":["Detect geodetic fields and branch the lookup value type accordingly.","Keep a helper metres_to_degrees(m, lat) for approximate conversions.","Document per-backend behaviour of dwithin in the project's GIS README."],"tags":["spatialite","lookup","dwithin","geodetic","gis"],"analyzedSha":"ae25a40be07e8a749edf526df37c93e59d4a22c9","analyzedAt":"2026-08-06T21:46:51.801Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}