假设我有一个模型:
class House(models.Model):
(...)
price = models.DecimalField(decimal_places=2, max_digits=8)
area = models.DecimalField(decimal_places=2, max_digits=6)
我有一个用于搜索房屋的表格:
class SearchHouseForm(forms.Form):
price_min = forms.DecimalField(required=False, initial=0, decimal_places=2, max_digits=8)
price_max = forms.DecimalField(required=False, initial=999999, decimal_places=2, max_digits=6)
和视图函数:
def search_for_houses(request):
queryset = House.objects.all()
if request.method == 'GET' and 'search-submit-button' in request.GET:
form = SearchHouseForm(request.GET)
if form.is_valid():
queryset = queryset.filter(
price__lte = form.cleaned_data['price_max'],
price__gte = form.cleaned_data['price_min']
)
else:
(...)
return render(request, template, {'house_list': queryset, 'form': form})
我有.filter()
-ing的问题。当且仅当用户在表单字段中提供任何值时,我想应用过滤器。如果该price_max
字段留空,则只price__gte = form.cleaned_data['price_min']
应应用 。如果price_max
和price_min
都留空,House
则应返回所有对象。目前我得到ValueError Cannot use None as a query value
有没有干净的方法来做到这一点?我唯一能想到的是if
所有这些可选字段的一长串语句:
if form.cleaned_data['price_max'] is not None:
queryset = queryset.filter((...))
if form.cleaned_data['price_min'] is not None:
queryset = queryset.filter((...))
(...)
这似乎不是一个好主意,特别是如果我想应用大量这样的可选过滤字段。
在只有两个过滤器的情况下,我会按照你的建议继续使用if ...
条件。
但如果您想在未来构建更复杂的查询,请考虑使用Q
对象。这里有一篇很好的博客文章,其中展示了一些示例。例如,您可以创建一个过滤器字典,并循环遍历您的字段并在字段值已填充时添加 Q 过滤器。
这个方向的东西:
queries = {'price_max': "price__lte", 'price_min': "price__gte"}
predicates = []
for field, value in cleaned_data.items():
if value and field in queries:
predicates.append((queries[field], value))
q_list = [Q(x) for x in predicates]
queryset = queryset.filter(reduce(operator.and_, q_list))
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句