从迭代中实现django OR查询的最佳实践方法?

时间:2012-08-27 20:08:37

标签: python django django-models

我正在实施一个一次性数据导入器,我需要搜索现有的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)

4 个答案:

答案 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)

应该做的。