我正在实施一个一次性数据导入器,我需要搜索现有的slugs。 slu are是一个阵列。将数组转换为OR
查询的最佳实践方法是什么?
我想出了以下内容,它可以运行,但感觉就像过多的代码来完成这么简单的事情。
# slug might be an array or just a string
# ex:
slug = [ "snakes", "snake-s" ] # in the real world this is generated from directory structure on disk
# build the query
query = MyModel.objects
if hasattr(slug, "__iter__"):
q = Q()
for s in slug:
q = q.__or__(Q(slug=s))
query = query.filter(q)
else:
query = query.filter(slug=slug)
答案 0 :(得分:4)
slug = ["snakes", "snake-s" ] # in the real world this is generated from directory structure on disk
# build the query
query = MyModel.objects
if hasattr(slug, "__iter__"):
q_list = []
for s in slug:
q_list.append(Q(slug=s))
query = query.filter(reduce(operator.or_, q_list))
else:
query = query.filter(slug=slug)
q_list = []
创建一个Q子句列表reduce(operator.or_, q_list)
使用或运算符请阅读:http://www.michelepasin.org/techblog/2010/07/20/the-power-of-djangos-q-objects/
@MostafaR - 如果我们想要的话,我们确定可以将整个代码块压缩到一行(见下文)。虽然它在那个级别不再具有可读性。说代码不是“Pythonic”只是因为它没有被减少和被诅咒是愚蠢的。可读代码是国王恕我直言。同样重要的是要记住我的答案的目的是通过操作员技术显示reduce
。我的答案的其余部分是绒毛,以显示原始问题的背景技术。
result = MyModel.objects.filter(reduce(operator.or_, [Q(slug=s) for s in slug])) if hasattr(slug, "__iter__") else MyModel.objects.filter(slug=slug)
答案 1 :(得分:1)
result = MyModel.objects.filter(slug__in=slug).all() if isinstance(slug, list) else MyModel.objects.filter(slug=slug).all()
答案 2 :(得分:0)
我相信在这种情况下你应该像这样使用django的__in
field lookup:
slugs = [ "snakes", "snake-s" ]
objects = MyModel.objects.filter(slug__in=slugs)
答案 3 :(得分:-1)
你发布的代码在很多方面都不会起作用(但我不确定它是否应该是更多伪代码?),但据我所知,这可能有所帮助:
MyModel.objects.filter(slug__in=slug)
应该做的。