Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter Django database for field containing any value in an array

I have a django model and a field representing a users full name. My client wants me to set up a filter to search for a user based on an array of strings where all of them have to be case insensitive contained within the full name.

For example

If a users full_name = "Keith, Thomson S."

And I have a list ['keith','s','thomson']

I want to perform the filter equivalent of

Profile.objects.filter(full_name__icontains='keith',full_name__icontains='s',full_name__icontains='thomson') 

The problem is this list can be of dynamic size - so I do not know how to do this.

Anyone have any ideas?

like image 918
xizor Avatar asked Jan 20 '12 23:01

xizor


People also ask

How can I filter a Django query with a list of values?

To filter a Python Django query with a list of values, we can use the filter method with in . to search Blog entries with pk set to 1,4 or 7 by calling Blog. objects. filter with the pk_in argument set to [1, 4, 7] .

How do I filter records in Django?

Django framework has a built-in filter() method to filter data from the database tables. A table can contain many records and sometimes determining some specific data are required based on the particular criteria. This task becomes easier by using the filter() method in different ways.

What is the difference between contains and Icontains in Django?

Definition and Usage The contains lookup is used to get records that contains a specified value. The contains lookup is case sensitive. For a case insensitive search, use the icontains lookup.

How do you use get and filter together in Django?

Basically use get() when you want to get a single unique object, and filter() when you want to get all objects that match your lookup parameters. Show activity on this post. Show activity on this post. Show activity on this post.


1 Answers

Make successive calls to filter, like so:

queryset = Profile.objects.all() strings = ['keith', 's', 'thompson'] for string in strings:     queryset = queryset.filter(full_name__icontains=string) 

Alternatively you can & together a bunch of Q objects:

condition = Q(full_name__icontains=s[0]) for string in strings[1:]:     condition &= Q(full_name__icontains=string) queryset = Profile.objects.filter(condition)  

A more cryptic way of writing this, avoiding the explicit loop:

import operator # ... condition = reduce(operator.and_, [Q(full_name__icontains=s) for s in strings]) queryset = Profile.objects.filter(condition) 
like image 192
Ismail Badawi Avatar answered Oct 13 '22 15:10

Ismail Badawi