[Django]-How to Query model where name contains any word in python list?

61๐Ÿ‘

โœ…

You could use Q objects to constuct a query like this:

from django.db.models import Q

ob_list = data.objects.filter(reduce(lambda x, y: x | y, [Q(name__contains=word) for word in list]))

Edit:

reduce(lambda x, y: x | y, [Q(name__contains=word) for word in list]))

is a fancy way to write

Q(name__contains=list[0]) | Q(name__contains=list[1]) | ... | Q(name__contains=list[-1])

You could also use an explicit for loop to construct the Q object.

๐Ÿ‘คIsmail Badawi

33๐Ÿ‘

ob_list = data.objects.filter(name__in=my_list)

And BTW, avoid using the variable name โ€œlistโ€ (Or any other python standard keyword), lest you get into some weird bugs later.

Update: (I guess your question was updated too, because when I wrote the answer, I didnโ€™t see the part where you wrote you need a contains match and not an exact match)

You can do that using the regex search too, avoiding many Q expressions (which end up using that many where โ€œandโ€ clauses in the SQL, possibly dampening the performance), as follows:

data.objects.filter(name__regex=r'(word1|word2|word3)')
๐Ÿ‘คlprsd

2๐Ÿ‘

obj_list = [obj for obj in data.objects.all() if any(name in obj.name for name in list)]

Edit: Just re-read your question. Donโ€™t know if you can do that with filter but you can do it with a list comprehension or generator expression.

๐Ÿ‘คagf

1๐Ÿ‘

For anyone comparing Arrays, you could use Djangoโ€™s Overlap filter to achieve this.

From the docs:

Returns objects where the data shares any results with the values passed. Uses the SQL operator &&.

So, you would simply write:

ob_list = data.objects.filter(name__overlap=my_list)
๐Ÿ‘คDanny Vu

0๐Ÿ‘

very simple just use "__in" , as the follwing :

my_list= ['word1','word2','word3']
ob_list = model.objects.filter(your-field__in=my_list)

1- change "model" by your model name.

2- change "your-field" by your field name.

i hope this helpful .

๐Ÿ‘คK.A

0๐Ÿ‘

Just thought I would add this here. Built this off the "use Q objects" answer with a little tweaking to get search to work for multiple partial word matches across specified fields.

from functools import reduce
from django.contrib.postgres.search import SearchVector
from django.db.models import Q

s = "Input text to match to fields in SearchVector"
words = list(i for i in s.split(" "))
search_data = (
    Item.objects.annotate(
        search=SearchVector(
            "id",
            "name",
        ),
    )
    .filter(
        reduce(
            lambda x, y: x & y,
            [Q(search__contains=word) for word in words],
        )
    )
    .all()
)
๐Ÿ‘คSilimadev

Leave a comment