Django 使用 GET 过滤搜索结果

Django Filtering Search Results using GET

我想为我的 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)

您不能使用字符串将参数传递给 .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 等)