Python Django使用GET筛选搜索结果

Python Django使用GET筛选搜索结果,python,django,geodjango,Python,Django,Geodjango,我想为我的ListView构建一个过滤器,以进一步缩小搜索结果的范围 目前,用户在其所在区域搜索服务,并在付费或免费服务(使用单选按钮)之间进行选择 forms.py: class LocationForm(forms.Form): Place = forms.CharField(label='Place') Lat = forms.FloatField() Lng = forms.FloatField() CHOICES = [('Free', 'Paid'),

我想为我的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()
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
视图。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()
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\u filter
,这是我想要运行的用于区分免费服务和付费服务的附加筛选器不起作用,并给了我这个错误:
太多的值无法解包(预期为2)

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

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

vt_filter = {
    'Free': True,
}
然后通过它进入过滤器:

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

注意:

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()
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
就设计而言,服务可以是免费的,也可以是付费的。因此,您可以省略型号的
付费
字段,只使用
免费
,因为如果服务是免费的,则
免费=真
否则
免费=假


此外,使用标准为您的代码命名更有利于代码的可读性。(例如,
SearchPoint
应该是
SearchPoint
等等)

嘿,@Roma我在想,你觉得我的答案有用吗?嗨,约翰,是的,我已经做了标记,很高兴知道:)