我正在使用django rest框架创建api和django-filter,以为用户提供很好的方式来查看过滤器如何在网站的可浏览api部分中工作。
我需要通过方法调用的结果来过滤查询集。不幸的是,它需要用户提供3个参数(使用lat,lng,radius计算到中心点的距离)。
我知道我可以在filterset中声明一个非模型字段,并带有要调用的方法,但是只有一个参数传递给该方法。 我可以声明3个非模型字段,但是我以3种不同的方法结束,或者用1个更改参数的方法调用同一方法3次。 示例代码:
class PersonFilter(FilterSet):
status = ChoiceFilter(field_name='status', choices=Person.STATUS_CHOICES)
# I show an example of what I need to achieve below, obviously it will not work as
# I need to give the user 3 fields to fill in and call the method only once with their values...
latitude = NumberFilter(label='latitude', method='check_if_in_range')
longitude = NumberFilter(label='longitude', method='check_if_in_range')
radius = NumberFilter(label='radius', method='check_if_in_range')
class Meta:
model = Person
fields = 'status', 'latitude', 'longitude', 'radius'
example method to filter by 3 parameters:
def check_if_in_range(self, queryset, name, value):
here I need access to the values from 3 non model form fields...
do calculation and filter the queryset
return <filtered queryset>
这甚至可行吗? 我希望我的用户能够使用:
<base_url>?longitude=234234&latitude=232342&radius=34
通过API过滤人员... 谢谢您的时间和帮助!
Tomasz
答案 0 :(得分:0)
您可以执行以下操作:
class PersonFilter(FilterSet):
status = ChoiceFilter(field_name='status', choices=Person.STATUS_CHOICES)
radius = NumberFilter(label='radius', method='check_if_within_range')
class Meta:
model = Person
fields = 'status', 'radius'
def check_if_within_range(self, queryset, name, value):
base_point = Point(latitude=float(self.request.GET.get("latitude")),
longitude=float(self.request.GET.get("longitude")))
return queryset.distance_within(base_point, value)
根据您要如何计算距离和过滤查询集,需要使用自定义方法。在这里,我假设您将在自定义查询集管理器中使用distance_within()
方法。
您可以根据需要/结构进行重构。