8

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 a parameter string (lets call the variable "querystring" is contained in the field keyword:

results = SomeModel.objects.filter(keyword_icontains=querystring).all()

which I found in the django docs

Question, how do I filter for the objects whose field values are contained in the querystring variable?

Apologies if my question is confusing... maybe an example will clarify... In django docs, if my keyword field contains,for example, 'python-django', then, for a querystring that contains 'django', I can extract the object that contains that field with an

results=SomeModel.objects.filter(keyword_icontains=querystring).all()
or results=SomeModel.objets.filter(keyword_icontains='django').all()

But say, I want to extract all rows/objects whose keyword field is contained in a querystring? For example, if querystring contains 'In django, how do I create a filter'? then I want results to contain all objects whose keyword fields have the values 'django', 'filter', etc...

12
  • 1
    Querystring containing the field? As in the value of querystring containing field name of the model? Commented Jun 13, 2016 at 4:29
  • @RajeshYogeshwar, as in the value of the querystring containing the value of the field of the model... Commented Jun 13, 2016 at 4:32
  • Your current example is incorrect, unless querystring is actually the string "querystring". And the SQL equivalent is then SELECT ... WHERE keyword IKE '%querystring%'. Possibly, that is causing confusion as to what your question is, and the likely answer. Commented Jun 13, 2016 at 4:38
  • 1
    @RVC thats what I asked. You are trying to do a LIKE query on the field name itself. May I know exactly the purpose of same to give better understanding of what you are trying to achieve? Commented Jun 13, 2016 at 4:39
  • 1
    You're matching on words from the input sentence, afaict. But you'll have to be specific in your question whether that's really the case. What about punctuation or whitespace? Include or exclude those? What about possessives like "Searching in StackOverflow's questions" or abbrevations like "isn't"? Commented Jun 13, 2016 at 6:06

2 Answers 2

8

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).

Sign up to request clarification or add additional context in comments.

3 Comments

It should be 'Q(keyword__icontains=word)', doucle underscore
its says Q() is undefined variable
@FaizHameed import it with: from django.db.models import Q
8

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

2 Comments

I'm not understanding; all I get is "querystring is not defined". Which makes sense, because its not defined... Can you give an example?
Nevermind, I figured it out. querystring inside of Value is the value you are wanting, while 'keyword' is the field you want to check against.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.