我想为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)
答案 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
等。)