【问题标题】:django-filter (django rest framework) - method filter with 3 parametersdjango-filter (django rest framework) - 具有 3 个参数的方法过滤器
【发布时间】:2019-05-15 13:15:24
【问题描述】:

我正在使用 django rest 框架来创建一个 api 和 django-filter 来为用户提供很好的方式来查看过滤器在站点的可浏览 api 部分中是如何工作的。

我需要通过方法调用的结果来过滤查询集。不幸的是,它需要用户提供 3 个参数(使用 lat、lng、radius 计算距中心点的距离)。

我知道我可以在过滤器集中声明一个非模型字段,并使用一个方法来调用,但只有一个参数被传递给该方法。 我可以声明 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 过滤人员... 感谢您的时间和帮助!

托马斯

【问题讨论】:

    标签: methods filter django-rest-framework django-filter


    【解决方案1】:

    你可以这样做:

    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() 方法。

    您可以根据需要/结构进行重构。

    【讨论】:

      猜你喜欢
      • 2017-06-13
      • 2018-02-23
      • 2018-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 2018-07-28
      • 2021-07-16
      相关资源
      最近更新 更多