0

Using django, I want to dynamically search for text across multiple fields. I have a list of fields to search across as well as the text to search against. I also have an initial queryset to query against. Something along these lines:

def dynamic_search(queryset):
    search_fields = ["search_field1", "search_field2", "search_field3"]
    search_text = "dummy_text"

    # I want to dynamically generate this query
    qs.filter(Q(search_field1__contains=search_text) | Q(search_field2__contains=search_text) | Q(search_field3__contains=search_text))

The issue is that search_fields is a generic list so I need to dynamically query against those fields as well. Is there a good way to do this in django?

itsvinayak
  • 140
  • 1
  • 16
Atul Bhatia
  • 1,633
  • 5
  • 25
  • 50

2 Answers2

1

You can use the or_ method from the operator builtins, a list comprehension and the reduce builtin like this:

from django.db.models import Q
import operator


def dynamic_search(queryset):
    search_fields = ["search_field1", "search_field2", "search_field3"]
    search_text = "dummy_text"
    queryset.filter(reduce(operator.or_, [Q(**{'{0}__contains'.format(search_field): search_text}) for search_field in search_fields]))
garnertb
  • 9,454
  • 36
  • 38
0

Not sure about a Django specific one, but you could use eval.

N.B: THIS IS A BAD IDEA IF YOU ARE USING USER INPUT AND COULD OPEN UP ALL SORTS OF INSECURITIES. - but if you are in complete control of it it should be fine.

x = []
for search_field in search_fields:
    x.append(eval("qs.filter(Q({}__contains={})".format(search_field, search_text))

I'm storing in a list just for convenience. If you are allowed to use the | operator in your Django query - I don't know i you can, you could just assign it to a variable.

NDevox
  • 4,056
  • 4
  • 21
  • 36