scriptdiddy
scriptdiddy

Reputation: 1265

Django Multiple Filter with list

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

Upvotes: 0

Views: 1145

Answers (2)

karthikr
karthikr

Reputation: 99620

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)

Upvotes: 3

deadbeef404
deadbeef404

Reputation: 623

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'])

Upvotes: 0

Related Questions