如果空字段返回所有元素,则在 Django 中查询集

Posted

技术标签:

【中文标题】如果空字段返回所有元素,则在 Django 中查询集【英文标题】:Queryset in Django if empty field returns all elements 【发布时间】:2018-05-01 18:01:50 【问题描述】:

我想在 Django 中做一个使用表单方法的过滤器。 如果用户键入 de var,则应在数据集中查询该 var,如果留空则应带入所有元素。

我该怎么做?

我是 Django 新手

if request.GET.get('Var'):
    Var = request.GET.get('Var')
else:
    Var = WHAT SHOULD I PUT HERE TO FILTER ALL THE ELEMNTS IN THE CODE BELLOW

models.objects.filter(Var=Var)

【问题讨论】:

【参考方案1】:

从安全的角度来看,允许用户将数据直接输入到搜索词中并不是一个好主意(如果您使用其中任何一个,则绝对不应该对原始 SQL 查询执行此操作。)

考虑到这一点,您可以利用字典语法创建更动态的过滤器,或随时修改查询集:

选项 1:字典语法

def my_view(request):
  query = 
  if request.GET.get('Var'):
     query['Var'] = request.GET.get('Var')
  if request.GET.get('OtherVar'):
    query['OtherVar'] = request.GET.get('OtherVar')
  if request.GET.get('thirdVar'):
    # Say you wanted to add in some further processing
    thirdVar = request.GET.get('thirdVar')
    if int(thirdVar) > 10:
       query['thirdVar'] = 10
    else:
       query['thirdVar'] = int(thirdVar)
  if request.GET.get('lessthan'):
    lessthan = request.GET.get('lessthan')
    query['fieldname__lte'] = int(lessthan)
  results = MyModel.objects.filter(**query)

如果没有任何内容添加到查询字典并且它是空的,那将相当于执行 MyModel.objects.all()

如果你想尝试做这样的事情(这将是一个坏主意),我上面的安全说明适用:

MyModel.objects.filter(**request.GET)

Django 具有良好的安全记录,但这不如预测用户将进行的查询类型安全。如果恶意网站用户知道您的架构,他们可以调整他们的查询语法以沿着非索引字段进行繁重的查询,这也可能是一个大问题。

选项 2:修改查询集 或者,您可以从所有内容的查询集开始,然后进行相应的过滤

def my_view(request):
  results = MyModel.objects.all()
  if request.GET.get('Var'):
     results = results.filter(Var=request.GET.get('Var'))
  if request.GET.get('OtherVar'):
    results = results.filter(OtherVar=request.GET.get('OtherVar'))
  return results

【讨论】:

谢谢罗伯特,它工作得很好。在第一个选项中,如果我只想将其中一个变量设置为大于一个数字,我该如何进行? 很高兴为您提供帮助!关于您的问题,您可以通过更改字典来更改查询,就像使用任何其他字典一样,使用条件。我在示例视图中制作了 thirdVar 示例,但如果您有更具体的用例想要构建,请随时告诉我。 是的,我需要更多帮助,我无法联系到.. 示例如下,用户将在表单字段中输入一个数字并提交。系统应该查询并返回所有具有以下数字的元素。 您可以使用__语法来访问更复杂的查询功能。例如,假设您需要过滤“usercount”字段以查找用户数小于 10 的项目,您可以执行 MyModel.objects.filter(usercount__lte=10)(lte 代表“小于或等于”)。我在示例代码中创建了第四个过滤器 非常感谢罗伯特。它成功了!!感谢您的帮助.. 最好的问候【参考方案2】:

一种更简单、更明确的方法是:

if request.GET.get('Var'):
    data = models.objects.filter(Var=request.GET.get('Var'))
else:
    data = models.objects.all()

【讨论】:

以上是关于如果空字段返回所有元素,则在 Django 中查询集的主要内容,如果未能解决你的问题,请参考以下文章

空查询返回数据库中的所有字段。姜戈

使用 ORM Django 过滤新更新的查询集返回空查询集

仅具有查看权限的 Django 模型表单将所有字段排除在外

查询不返回空品牌字段

在 django 中查询多对多字段会产生一个空查询集

什么基于可空表单字段的访问查询条件将返回我需要的内容?