[Django]-How to dynamically provide lookup field name in Django query?

39👍

✅

I think there may be a better way to do this with the Django query system. Here’s how to do it your way.

Python allows you to pass dictionaries to be used as argument lists by prefixing them with **.
With a spot of luck, you should be able to do something like this:

lookup = "%s__contains" % field
results.append(Item.objects.filter(**{ lookup: keyword}))

62👍

I would prefer to use the Q object for something like this.

from django.db.models import Q

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

Qr = None
for field in fields:
    q = Q(**{"%s__contains" % field: keyword })
    if Qr:
        Qr = Qr | q # or & for filtering
    else:
        Qr = q

# this you can now combine with other filters, exclude etc.    
results = MyModel.objects.filter(Qr)

7👍

I like DialZ’s answer but for performance reasons you should build the query and then hit the database once instead of concatenating all the results into a list:

keyword = 'keyword'
fields = ['foo', 'bar', 'baz']

# this makes an empty queryset object which we can
# add to later using the | operator
results = Item.objects.none()

for field in fields:
    lookup = "%s__contains" % field
    query = {lookup : keyword}
    results = results | Item.objects.filter(**query)

I havn’t done one of these in a while, but I’m pretty sure django will not actually hit the database at all in this code. It will only perform a query when you access the data contained in the records

Leave a comment