Open
Description
My setup it is something along the lines of this:
class Location(models.Model):
point = models.PointField(geography=True)
class LocationFilterSet(filters.FilterSet):
within = GeometryFilter(
field_name="point", srid=4326, method="filter_within"
)
class Meta:
model = Location
fields = ["within"]
def filter_within(self, qs, name, value):
return qs.filter(**{f"{name}__dwithin": (value, Distance(1))})
class LocationViewSet(ModelViewSet):
queryset = Location.objects.all()
filter_backends = (django_filters.DjangoFilterBackend, )
filter_class = LocationFilterSet
When I query the filter providing invalid input http://localhost:8000/api/locations/?within={"type":"Feature","I am not valid":"1,1,1"}
I get the following exception:
return self.application(environ, start_response)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/wsgi.py", line 142, in __call__
response = self.get_response(request)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 78, in get_response
response = self._middleware_chain(request)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 36, in inner
response = response_for_exception(request, exc)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 125, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "/var/www/.venv/lib/python3.7/site-packages/django_extensions/management/technical_response.py", line 37, in null_technical_500_response
six.reraise(exc_type, exc_value, tb)
File "/var/www/.venv/lib/python3.7/site-packages/six.py", line 692, in reraise
raise value.with_traceback(tb)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/var/www/.venv/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/var/www/.venv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/viewsets.py", line 116, in view
return self.dispatch(request, *args, **kwargs)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 495, in dispatch
response = self.handle_exception(exc)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 455, in handle_exception
self.raise_uncaught_exception(exc)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/views.py", line 492, in dispatch
response = handler(request, *args, **kwargs)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/mixins.py", line 40, in list
queryset = self.filter_queryset(self.get_queryset())
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework/generics.py", line 152, in filter_queryset
queryset = backend().filter_queryset(self.request, queryset, self)
File "/var/www/.venv/lib/python3.7/site-packages/rest_framework_json_api/django_filters/backends.py", line 134, in filter_queryset
return super(DjangoFilterBackend, self).filter_queryset(request, queryset, view)
File "/var/www/.venv/lib/python3.7/site-packages/django_filters/rest_framework/backends.py", line 94, in filter_queryset
if not filterset.is_valid() and self.raise_exception:
File "/var/www/.venv/lib/python3.7/site-packages/django_filters/filterset.py", line 206, in is_valid
return self.is_bound and self.form.is_valid()
File "/var/www/.venv/lib/python3.7/site-packages/django/forms/forms.py", line 185, in is_valid
return self.is_bound and not self.errors
File "/var/www/.venv/lib/python3.7/site-packages/django/forms/forms.py", line 180, in errors
self.full_clean()
File "/var/www/.venv/lib/python3.7/site-packages/django/forms/forms.py", line 381, in full_clean
self._clean_fields()
File "/var/www/.venv/lib/python3.7/site-packages/django/forms/forms.py", line 399, in _clean_fields
value = field.clean(value)
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/forms/fields.py", line 63, in clean
geom = super().clean(value)
File "/var/www/.venv/lib/python3.7/site-packages/django/forms/fields.py", line 147, in clean
value = self.to_python(value)
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/forms/fields.py", line 42, in to_python
value = GEOSGeometry(value)
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/geos/geometry.py", line 705, in __init__
ogr = gdal.OGRGeometry.from_json(geo_input)
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/gdal/geometries.py", line 161, in from_json
return OGRGeometry(OGRGeometry._from_json(force_bytes(geom_input)))
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/gdal/geometries.py", line 143, in _from_json
ptr = capi.from_json(geom_input)
File "/var/www/.venv/lib/python3.7/site-packages/django/contrib/gis/gdal/prototypes/errcheck.py", line 84, in check_geom
raise GDALException('Invalid geometry pointer returned from "%s".' % func.__name__)
django.contrib.gis.gdal.error.GDALException: Invalid geometry pointer returned from "OGR_G_CreateGeometryFromJson".
I've kind of fixed the issue by using the code below. This doesn't seem like a hugely eloquent solution though.
from django.contrib.gis import forms
from rest_framework_gis.filters import GeometryFilter as BaseGeometryFilter
class GeometryField(forms.GeometryField):
"""Catch GDALException."""
def to_python(self, value):
"""Catch GDALException."""
try:
return super().to_python(value)
except GDALException as e:
raise forms.ValidationError("Invalid geometry value.")
class GeometryFilter(BaseGeometryFilter):
"""Catch GDALException."""
field_class = GeometryField
Is there something I'm missing? I've read through the docs and check the issues and I can't seem to find a better solution.
Metadata
Metadata
Assignees
Type
Projects
Status
To do (Python & Django)