[Django]-Best practices method of implementing a django OR query from an iterable?

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 = [] create a list of Q clauses
  • reduce(operator.or_, q_list) implode the list with or operators

read this: http://www.michelepasin.org/techblog/2010/07/20/the-power-of-djangos-q-objects/

@MostafaR – sure we could crush my entire codeblock down to one line if we wanted (see below). Its not very readable anymore at that level though. saying code isn’t “Pythonic” just because it hadn’t become reduced and obsfucated is silly. Readable code is king IMHO. Its also important to keep in mind the purpose of my answer was to show the reduce by an operator technique. The rest of my answer was fluff to show that technique in context to the original question.

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👍

result = MyModel.objects.filter(slug__in=slug).all() if isinstance(slug, list) else MyModel.objects.filter(slug=slug).all()

0👍

I believe in this case you should use django’s __in field lookup like this:

slugs = [ "snakes", "snake-s" ]
objects = MyModel.objects.filter(slug__in=slugs)
👤Pero

-1👍

The code that you posted will not work in many ways (but I am not sure if it should be more pseudocode?), but from what I understand, this might help:

MyModel.objects.filter(slug__in=slug)

should do the job.

Leave a comment