Django 1.11:在 url 中的查询参数中浮动

Posted

技术标签:

【中文标题】Django 1.11:在 url 中的查询参数中浮动【英文标题】:Django 1.11: Float in query param in url 【发布时间】:2018-11-22 22:28:58 【问题描述】:

TL;DR:如何接受浮点数作为 url 中的查询参数?

我用 Django Rest Framework 编写了一个 API 视图。 API 应该能够使用 GET 请求按地址坐标列出房屋。这意味着用户应该能够发送包含坐标的查询作为获取请求,并且应该返回这些坐标周围所有房屋的列表。

这是视图(views.py):

class HouseListAPIView(generics.ListAPIView):
    serializer_class = HouseListSerializer
    queryset = House.objects.all()

    def get_queryset(self):
        qs = self.queryset
        longitude = self.request.query_params.get('lon', None)
        latitude = self.request.query_params.get('lat', None)
        radius = self.request.query_params.get('radius', 1)
        if radius < 0 or radius >= 1:
            radius = 1
        if longitude is not None and latitude is not None:
            qs = qs.filter(
                address__coordinates__latitude__lte=get_lat_max(longitude, latitude, radius),
                address__coordinates__latitude__gte=get_lat_min(longitude, latitude, radius),
                address__coordinates__longitude__lte=get_lon_max(longitude, latitude, radius),
                address__coordinates__longitude__gte=get_lon_min(longitude, latitude, radius)
            )
        return qs

这里是辅助函数(utils.py):

import geopy
from geopy.distance import VincentyDistance


def get_lat_lon_values_from_radius(d, lat1, lon1, b):
    """
    given: lat1, lon1, b = bearing in degrees, d = distance in kilometers
    """
    origin = geopy.Point(lat1, lon1)
    destination = VincentyDistance(kilometers=d).destination(origin, b)

    lat2, lon2 = destination.latitude, destination.longitude
    return lat2, lon2


def get_lat_max(lat1, lon1, d=1):
    # latitude = north / south
    return int(get_lat_lon_values_from_radius(d, lat1, lon1, 0)[0])


def get_lat_min(lat1, lon1, d=1):
    return int(get_lat_lon_values_from_radius(d, lat1, lon1, 180)[0])


def get_lon_max(lat1, lon1, d=1):
    # longitude = west / east
    return int(get_lat_lon_values_from_radius(d, lat1, lon1, 90)[1])


def get_lon_min(lat1, lon1, d=1):
    return int(get_lat_lon_values_from_radius(d, lat1, lon1, 270)[1])

我的问题是我目前设置了一个空查询,因为 url 中的数字由于某种原因被四舍五入:

input_lat: 50.7758666, input_lon: 6.0849401
lat_max: 6
lat_min: 6
lon_max: 50
lon_min: 50

如何将查询参数中的经度和纬度作为浮点数传递给视图?

【问题讨论】:

查询参数是字符串。所以self.request.query_params.get('lon', None) 会给你字符串。尝试将其转换为浮点数:longitude = float(self.request.query_params.get('lon', None)). 用这个解决了。谢谢 :) 如果您将其写为答案,我会接受。 【参考方案1】:

(代表问题作者发布答案)

使用 neverwalkaloner 的答案,我这样解决了:

    def get_queryset(self):
        qs = self.queryset
        longitude = self.request.query_params.get('lon', None)
        latitude = self.request.query_params.get('lat', None)
        if longitude is not None and latitude is not None:
            longitude = float(longitude.replace(',', '.'))
            latitude = float(latitude.replace(',', '.'))
            radius = self.request.query_params.get('radius', 1)
            if radius < 0 or radius >= 1:
                radius = 1
            qs = qs.filter(
                address__coordinates__latitude__lte=get_lat_max(longitude, latitude, radius),
                address__coordinates__latitude__gte=get_lat_min(longitude, latitude, radius),
                address__coordinates__longitude__lte=get_lon_max(longitude, latitude, radius),
                address__coordinates__longitude__gte=get_lon_min(longitude, latitude, radius)
            )
        return qs

【讨论】:

【参考方案2】:

当您在视图中访问query_params 时,它会为您提供字符串对象。您应该将其转换为浮点数,如下所示:

longitude = float(self.request.query_params.get('lon', None))

【讨论】:

以上是关于Django 1.11:在 url 中的查询参数中浮动的主要内容,如果未能解决你的问题,请参考以下文章

Django 1.11:模板中的 URL 函数未按预期工作

Django-1.11中文文档-模型Models

Django 1.11 404 页面,而 Debug=True

Django Pagination - 查询参数(url)

在Django 1.11更改视图中禁用原子事务

如何在字符串中添加/作为Django URL中的参数?