参数为无时查询 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)
为您提供查询集,其中 y
column 为非空 (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)
...
如果要处理的参数太多,你可以使用这样的东西;假设x
、y
、z
存储在字典中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 REST Framework 中显示查询参数选项 - Swagger