Say, I have a model with a text field:
class SomeModel
keyword=models.CharField(null=True, max_length=255)
Now, I know how to check if
You'll have to split your input into words (depending on your definition of "word"), and then iterate over them, concatenating the various resulting querysets (most of which are likely to be empty).
To split, you could use a regex, catching all letters and the apostrophe (but you'll miss a smart-quote, if someone uses that as input instead of the standard ASCII apostrophe):
words = re.split(r"[^A-Za-z']+", querystring)
Then loop and filter:
query = Q() # empty Q object
for word in words:
# 'or' the queries together
query |= Q(keyword_icontains=word)
results = SomeModel.objects.filter(query).all()
The above code is untested, and I got the idea to 'or' the queries and an empty Q() from this answer.
Depending on your next step(s), evaluating the query directly in each loop step, appending to a results
list, might work better for you (using e.g. itertools.chain
, as per this answer).
Here is a solution that will select SomeModel
rows whose keyword
is any substring of the querystring, not just complete words:
SomeModel.objects\
.annotate(querystring=Value(querystring, output_field=CharField()))\
.filter(querystring__icontains=F('keyword'))
See docs for info about annotate, Value expressions and F expressions