参数为无时查询 django

Posted

技术标签:

【中文标题】参数为无时查询 django【英文标题】:Query when parameter is none django 【发布时间】:2011-10-23 19:50:04 【问题描述】:

我想查询,比如

Model.objects.filter(x=x).filter(y=y).filter(z=z) 

...但在某些情况下,例如 y 为无。这实际上是在数据库中搜索 y 列中的空值——如果没有,是否有一种巧妙的方法可以基本上忽略该查询参数,即返回查询集

Model.objects.filter(x=x).filter(z=z)?

【问题讨论】:

【参考方案1】:

我不知道,如果我得到你的问题,但是

Model.objects.filter(x=x, y__isnull = False, z=z)

为您提供查询集,其中 ycolumn 为非空 (IS NOT NULL)。

Here's相关文档。

编辑:检查 y 是否为 None 并动态构建您的查询集:

if y is None:
    qs = Model.objects.filter(x=x).filter(z=z)
elif z is None:
    qs = Model.objects.filter(x=x).filter(y=y)
...

如果要处理的参数太多,你可以使用这样的东西;假设xyz 存储在字典中your values

your_values =  'x' : 'x value', 'y' : 'y value', 'z' : 'value'
arguments = 
for k, v in your_values.items():
    if v:
        arguments[k] = v

Model.objects.filter(**arguments)

【讨论】:

稍微编辑了我的问题,但不,这不是我的问题。如果我发布 x 和 z,但不发布 y,那么我希望能够找到所有包含 x 和 z 的元素,无论它们是否包含 y。就目前而言,它假设 y 为 None,并提取所有 x、z 和 y=None 的元素。 现在我明白了你想要达到的目标。请看我的回答。 这给我留下了 8 种可能的组合来检查... :( 我已经编辑了我的帖子,以反映您的评论。它现在应该适合你了:-)【参考方案2】:

这样的事情可能会奏效:

models = Model.objects.all()

variables = 'x':'x','y':'y','z':'z'

for key, value in variables.items():
    if key=='x' and value:
        models = models.filter(x=value)
    if key=='y' and value:
        models = models.filter(y=value)
    if key=='z' and value:
        models = models.filter(z=value)

因为QuerySets are lazy,这不涉及任何数据库活动。

【讨论】:

这是否意味着我只是将所有 100 亿个对象(请原谅夸大其词)加载到内存中? 不,因为 QuerySet 是惰性的(请参阅我的答案中发布的链接。)基本上models = Model.objects.all() 不会将任何内容加载到内存中,任何过滤器也不会加载,直到您实际评估 QuerySet。来自文档:You can stack filters together all day long, and Django won't actually run the query until the QuerySet is evaluated. 阅读该链接(惰性查询集)后,我认为答案是否定的。我对自己的反应太迟了。太棒了,谢谢。 这是完美的。再次感谢。 oneliner: Model.objects.filter(**dict([(k, v) for k, v in variables.iteritems() if v]))【参考方案3】:

对于原本非常可读的@rolling-stone 答案的更好方法:

models = Model.objects.all()

variables = 'x':x,'y':y,'z':z

for key, value in variables.items():
    if value is not None:
        models = models.filter(**key: value)

无论如何,根据特定的过滤器,您需要在同一个 .filter() 调用中一起应用过滤器,因此“盲目”方式仅适用于简单的情况。有关这些案例的更多信息,请参阅https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships。

【讨论】:

确实,这很好。谢谢。【参考方案4】:

您可以创建一个模型管理器,然后将其分配给您的模型,以便您可以将此管理器用于任何模型。这个解决方案更 Pythonic。

class GridManager(models.Manager):

    def applyFilters(self, *args, **kwargs):
         new_kwargs = 
         for eachKey in kwargs:
             val = kwargs[eachKey]
             if val != '' and val != None:
                 new_kwargs[eachKey] = val
         if new_kwargs:
             return super(GridManager, self).get_query_set().filter(*args, **new_kwargs)
         else:
             return super(GridManager, self).get_query_set()

将此经理分配给您的模型:

class some_model(models.Model):
     your fields.....
     ......
     objects = models.Manager()
     grid_manager = GridManager()

在您看来,您可以将上述管理器用作:

objects = some_model.grid_manager.applyFilters(x=value, y = value, z = None)

现在您不必担心 none 值。希望这会有所帮助。

【讨论】:

这很有趣,我得试试这个。谢谢。【参考方案5】:

你可以写:

filters = 'x':'abc', 'y':None, 'z':2
# here we filter out the None values of the dict 
filters = dict(filter(lambda (k, v): v is not None, filters.items()))

# We use the dict to create the query
qs = Model.objects.filter(**filters)

【讨论】:

以上是关于参数为无时查询 django的主要内容,如果未能解决你的问题,请参考以下文章

django字段查询参数及聚合函数

为啥这个 Django 原始 SQL 查询不返回输出?

如何在 Django REST Framework 中显示查询参数选项 - Swagger

Django框架——Q查询进阶ORM查询优化事务操作字段类型字段参数AjaxContent—Typeajax携带文件

如何将复杂的 django 查询构建为字符串

django分页后查询丢失