0

I have a list of selected items from a MultipleChoiceField object. After this list is created how can I filter on a Django model table so that it selects all of the items with any of the values in the list?

for example if i selected apples, oranges and strawberries, it returns all of the data from the FruitChoices table where the fruit_name is apples, or oranges, or strawberries.

from someApp.models import FruitChoices

def main(form_list):
    r = FruitChoices

    data = {}
    for form in form_list:
        data.update(form.cleaned_data)

        fruits = data['fruit_list']

        for item in fruits:
            result = r.objects.filter(fruit_name__contains='%s' % item)

    return result
2
  • Are you intentionally overwriting the result variabl in the loop? Commented Jul 10, 2013 at 3:01
  • I'm just using that for an example of what I am trying to do Commented Jul 10, 2013 at 3:07

2 Answers 2

3

You can do

import operator
from django.db import Q
r.objects.filter(reduce(operator.or_, (Q(fruit_name__contains=i) for i in fruits)))

The reason I recommend this approach is, if you use __in, it would match the whole word. But what you are looking for is __contains and there is no straight forward way of doing so directly in the ORM. Hence the Q objects

This is equivalent of:

q_list = []
for x in fruits:
    q_list.append(Q(fruit_name__contains=x)) 
q_filter = "|".join(q_list)
r.objects.filter(q_filter)
Sign up to request clarification or add additional context in comments.

Comments

0

You've said

where the fruit_name is apples, or oranges, or strawberries

and

so that it selects all of the items with any of the values in the list

but you're using a "__contains" filter.

Do you need to find substrings, ie. "bad strawberries"? If not, you could use the "__in" filter, and cut down the complexity of the entire problem.

r.objects.filter(fruit_name__in=data['fruit_list'])

2 Comments

This matches the whole word. Not contains.
Correct @karthikr, but the question was slightly vague as the example he gave was of an equivalence, and the text could be interpreted as not even needing a contains filter. This is why I posted this.

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.