[Fixed]-Difference between Django's __search vs. __icontains

18đź‘Ť

âś…

The difference is about the resulting SQL Query to be executed on the database… I personally prefer “__icontains” because is supported for all databases, and “__search” only for mysql (as django docs) (also supporting PostgreSQL in Django ≥ 1.10 — see documentation).

Look at the query for each method:

Using __search

>>> str(Contact.objects.filter(first_name__search='john').query)

'SELECT `contact_contact`.`id`, `contact_contact`.`title`, `contact_contact`.`first_name`, `contact_contact`.`last_name`, `contact_contact`.`user_id`, `contact_contact`.`role_id`, `contact_contact`.`organization_id`, `contact_contact`.`dob`, `contact_contact`.`email`, `contact_contact`.`notes`, `contact_contact`.`create_date` FROM `contact_contact` WHERE MATCH (`contact_contact`.`first_name`) AGAINST (john IN BOOLEAN MODE)'

Using __icontains

>>> str(Contact.objects.filter(first_name__icontains='john').query)

'SELECT `contact_contact`.`id`, `contact_contact`.`title`, `contact_contact`.`first_name`, `contact_contact`.`last_name`, `contact_contact`.`user_id`, `contact_contact`.`role_id`, `contact_contact`.`organization_id`, `contact_contact`.`dob`, `contact_contact`.`email`, `contact_contact`.`notes`, `contact_contact`.`create_date` FROM `contact_contact` WHERE `contact_contact`.`first_name` LIKE %john% '
👤Darwin

1đź‘Ť

as I tried, __search works just for whole word within multiple words (Incredible!), for example when my Book model contains an object with title='The little prance', while

Country.objects.filter(name__contais=’itt’)

returns one object,

Country.objects.filter(name__search=’itt’)

return nothing!

👤hadi ahadi

1đź‘Ť

Search has the advantage of allowing search for multiple fields:

>>> Entry.objects.annotate(
...     search=SearchVector('blog__tagline', 'body_text'),
... ).filter(search='cheese')
[
    <Entry: Cheese on Toast recipes>,
    <Entry: Pizza Recipes>,
    <Entry: Dairy farming in Argentina>,
]
👤hehe

Leave a comment