Django使用GET过滤搜索结果

时间:2017-09-10 23:33:25

标签: python django geodjango

我想为ListView构建一个过滤器,以进一步缩小搜索结果范围。

目前,用户在其所在区域搜索服务,并选择付费或免费服务(使用单选按钮)。

forms.py:

class LocationForm(forms.Form):
    Place = forms.CharField(label='Place')
    Lat = forms.FloatField()
    Lng = forms.FloatField()
    CHOICES = [('Free', 'Paid'),
               ('Free', 'Paid')]
    Type = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect())
    SearchRadius = forms.IntegerField()

views.py:

def get_context_data(self, **kwargs):
    if self.request.method == 'GET':
        form = LocationForm(self.request.GET)
        if form.is_valid():
            SearchPoint=Point(form.cleaned_data['Lng'],form.cleaned_data['Lat'])
            Radius = form.cleaned_data['SearchRadius']
            Type = form.cleaned_data['Type']
        else:
            form = LocationForm()
            SearchPoint=Point(0,0)
            Radius = 15
            Type='Free'
        try:
            Type
        except:
            vt_filter = "'Free'=True"
        else:
            if Type == 'Free':
                vt_filter="'Free'=True"
            else:
                vt_filter="'Paid'=True"



    context = super(IndexView, self).get_context_data(**kwargs)

    res = Model.objects.filter(location__distance_lte=
                                 (SearchPoint, D(km=Radius)),vt_filter)\
        .annotate(distance=Distance('location', SearchPoint))\
        .order_by('distance')

    context['model_list'] = res
    context['form'] = form

    return context

我想添加与.filter('Free'=True)类似的内容,以进一步缩小搜索范围。

在我的 models.py 中,对于Model,我分别有免费和付费的布尔字段。

Free = models.BooleanField(default=True)
Paid = models.BooleanField(default=False)

似乎vt_filter,我想要运行以区分免费和付费服务的额外过滤器不起作用,并且给了我这个错误:too many values to unpack (expected 2)

1 个答案:

答案 0 :(得分:1)

您不能使用字符串将参数传递给.filter()方法。

您可以做的是将其添加到字典中:

vt_filter = {
    'Free': True,
}

然后将unpacking传递给过滤器:

res = Model.objects.filter(
          **vt_filter,
          location__distance_lte=(SearchPoint, D(km=Radius))
      ).annotate(distance=Distance('location', SearchPoint))
      .order_by('distance')

<强> 注意:

作为设计问题,服务可以是免费付费。因此,您可以省略模型的Paid字段,并仅使用Free,因为如果服务是免费的,则Free=True其他Free=False

此外,您的代码可读性最好使用PEP8标准来命名您的内容。 (例如,SearchPoint应为search_point等。)