Geo Django 3.2 django.db.utils.OperationalError:没有这样的函数:lwgeom_version

问题描述 投票:0回答:2

我试图从用户当前位置获取附近的牙医列表。

用户当前位置(纬度和经度)通过查询参数发送。

牙医的位置保存在名为 location 的模型中,其中牙医的 id 是外键和唯一标识符。 我在 LocationSerializer 中使用了 drf_extra_fields.geo_fields 中的 PointField 字段

我正在使用 python 3.10 和 Django 3.2.8

型号

class Location(models.Model):
    id = models.OneToOneField(Dentist, on_delete=models.CASCADE, primary_key=True)
    location = models.PointField(srid=4326)

序列化器

from drf_extra_fields.geo_fields import PointField

class LocationSerializer(serializers.ModelSerializer):
    location = PointField()
    class Meta:
        model = Location
        fields = ['id', 'location']

查看

class NearByDentistView(APIView):
    def get(self,request):
        longitude = float(self.request.query_params.get('longitude'))
        latitude  = float(self.request.query_params.get('latitude'))
        user_location = Point(latitude,longitude,srid=4326)
        queryset = Location.objects.filter(location__distance_lte=(user_location, D(km=100)))

        serializer = LocationSerializer(queryset,many=True)
    
        return Response(serializer.data)

回复

Internal Server Error: /api/v1/user/dentist/nearby/
Traceback (most recent call last):
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 82, in _execute
    return self.cursor.execute(sql)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 421, in execute      
    return Database.Cursor.execute(self, query)
sqlite3.OperationalError: no such function: lwgeom_version

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\asgiref\sync.py", line 482, in thread_handler
    raise exc_info[1]
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\core\handlers\exception.py", line 38, in inner
    response = await get_response(request)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\core\handlers\base.py", line 233, in _get_response_async
    response = await wrapped_callback(request, *callback_args, **callback_kwargs)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\asgiref\sync.py", line 444, in __call__
    ret = await asyncio.wait_for(future, timeout=None)
  File "C:\Users\amanu\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 408, in wait_for
    return await fut
  File "C:\Users\amanu\AppData\Local\Programs\Python\Python310\lib\concurrent\futures\thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\asgiref\sync.py", line 486, in thread_handler
    return func(*args, **kwargs)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\views\generic\base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "D:\CODES\Django\SMILE_BACKEND\users\views.py", line 470, in get
    return Response(serializer.data)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\serializers.py", line 745, in data
    ret = super().data
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\rest_framework\serializers.py", line 663, in to_representation
    return [
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\query.py", line 280, in __iter__
    self._fetch_all()
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\query.py", line 1324, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\query.py", line 51, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1162, in execute_sql
    sql, params = self.as_sql()
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\compiler.py", line 528, in as_sql
    where, w_params = self.compile(self.where) if self.where is not None else ("", [])
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\compiler.py", line 445, in compile
    sql, params = node.as_sql(self, self.connection)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\where.py", line 81, in as_sql
    sql, params = compiler.compile(child)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\compiler.py", line 445, in compile
    sql, params = node.as_sql(self, self.connection)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\models\lookups.py", line 330, in as_sql
    sql, params = compiler.compile(distance_expr.resolve_expression(compiler.query))
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\models\sql\compiler.py", line 443, in compile
    sql, params = vendor_impl(self, self.connection)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\models\functions.py", line 297, in as_sqlite
    return super().as_sql(compiler, connection, **extra_context)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\models\functions.py", line 52, in as_sql
    function = connection.ops.spatial_function_name(self.name)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\backends\base\operations.py", line 115, in spatial_function_name
    if func_name in self.unsupported_functions:
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\utils\functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\backends\spatialite\operations.py", line 84, in unsupported_functions
    if not self.lwgeom_version():
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\backends\spatialite\operations.py", line 168, in lwgeom_version
    return self._get_spatialite_func('lwgeom_version()')
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\contrib\gis\db\backends\spatialite\operations.py", line 152, in _get_spatialite_func
    cursor.execute('SELECT %s' % func)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 98, in execute
    return super().execute(sql, params)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 79, in _execute
    with self.db.wrap_database_errors:
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\utils.py", line 82, in _execute
    return self.cursor.execute(sql)
  File "d:\CODES\Django\SMILE_BACKEND\venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 421, in execute
    return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: no such function: lwgeom_version
←[35;1mHTTP GET /api/v1/user/dentist/nearby/?latitude=69.764447962023&longitude=69.165280763008 500 [6.63, 127.0.0.1:13111]←[0m
python django django-rest-framework geodjango
2个回答
0
投票

您使用什么数据库? 错误消息指出缺少函数lwgeom_version

如果您使用的是 Django 框架使用的默认数据库 SQlite,则需要安装 SpatiaLite。 SpatiaLite 通过合并 LWGEOM(轻量级几何库)添加了对 SQlite 的空间支持,PostGIS 也使用该库来添加对 Postgres 数据库的支持。

对于空间查找,您正在查询以查找球面/曲面(地球)上的点(使用 srid=4326 或 WGS84 标准)的最短距离计算。这需要使用地理坐标系来计算几何图形之间的距离,而 SpatiaLite 似乎没有能力做到这一点。相反,您可以使用 Postgres(即 PostGis)使用

GeometryField.geography
等方法来添加此容量,并具有更好的性能。

您可以参考完整的 GeoDjango 模型 API 这里


0
投票

与 SpatiaLight 版本相比,Django 版本太旧时可能会出现此问题。 SpatiaLight 5.0 不支持 Django 3.2。尝试将 Django 更新为例如v4

© www.soinside.com 2019 - 2024. All rights reserved.