3

我正在实施一个一次性数据导入器,我需要在其中搜索现有的 slug。蛞蝓在一个数组中。将数组转换为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)
4

4 回答 4

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)使用 or 运算符内爆列表

阅读: 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)
于 2012-08-27T20:31:39.630 回答
1
result = MyModel.objects.filter(slug__in=slug).all() if isinstance(slug, list) else MyModel.objects.filter(slug=slug).all()
于 2012-08-27T20:30:05.247 回答
0

我相信在这种情况下,您应该像这样使用 django 的__in字段查找

slugs = [ "snakes", "snake-s" ]
objects = MyModel.objects.filter(slug__in=slugs)
于 2012-08-27T20:28:03.847 回答
-1

您发布的代码在很多方面都不起作用(但我不确定它是否应该是更多的伪代码?),但据我了解,这可能会有所帮助:

MyModel.objects.filter(slug__in=slug)

应该做的工作。

于 2012-08-27T20:23:19.087 回答