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