What is the difference between contains and icontains in Django?
When it comes to filtering or searching through data in Django, field lookups, especially, contains
and icontains
, are important when you wish to work with data that is case-sensitive.
But what’s the difference between the two Django field lookup types? Simply put, what other differences that arise when comparing contains
and icontains
, other than ‘contains
‘ being used for case-sensitive matching and ‘icontains
‘ used for case insensitive matching.
Here are the differences between contains and icontains field lookup types in Django:
contains (Model.objects.filter(field__contains=’lookup value’) | icontains (Model.objects.filter(field__icontains=’lookup value’) |
---|---|
contains is used for case-sensitive searches. Therefore the lookup will match all the objects where the field value matches the exact alphabet case used in the field lookup value. | icontains is used for case-insensitive searches. Therefore the lookup will match all the objects where the field value matches either small or capital letters. |
The query statement sent to the SQL database when using contains field lookup is implemented using the LIKE operator.The LIKE operator is used in a WHERE clause for searching for a particular case-sensitive pattern across a column.Example SQL code: SELECT * FROM Students WHERE StudentName LIKE 'a%'; | The query statement sent to the SQL database when using icontains field lookup is implemented using the ILIKE operator.The ILIKE operator is used in a WHERE clause for searching a case-insensitive pattern across a column. EXAMPLE SQL code: SELECT first_name FROM Students WHERE first_name ILIKE 'St%'; |
Example contains field lookup implementation in Django ORM:BlogPost.objects.filter(post_title__contains="Django Guide") contains will filter the results based on whether the field used in the lookup has a particular pattern/value matching the exact case. | Example icontains field lookup implementation in Django:BlogPost.objects.filter(post_title__icontains="DjAngo guiDe") icontains will filter the results based on whether the field used in the lookup has a particular pattern/value regardless of the case. |
If you wish to find all the object instances that match a particular field value or pattern without caring about the case, then you should use icontains
.
On the other hand, if you want to be precise and find matches that only match the case of your search term, then contains
should be your field lookup type.
What is the use of contains
and icontains
in Django?
contains
andicontains
can only be used for filtering data and cannot be used to update or delete records in your database.contains
andicontains
implementation only works as Django code. Thus, you cannot usecontains
andicontains
as code implementation for your SQL query statements. If you wish to write the SQL queries, you need to use theLIKE
andILIKE
operator equivalents.contains
andicontains
are used with fields that have textual data, such as CharField, SlugField (with alpha characters), and TextField. Django model fields containing purely numeric data, such as IntegerField, DecimalField, and FloatField cannot be used withcontains
andicontains
field lookup types.
Real-world examples of how you might use contains
and icontains
lookup types in Django
Search the database for particular products by name for an e-commerce website
In Django models:
# in your models.py
class Product(models.Model):
product_name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
In your views:
# in your views.py
def product_list(request):
search_query = request.GET.get('q')
if search_query:
products = Product.objects.filter(product_name__icontains=search_query)
else:
products = Product.objects.all()
return render(request, 'products.html', {'products': products})
Filter a list of blog posts by their titles
In Django models:
# models.py
class BlogPost(models.Model):
post_title = models.CharField(max_length=200)
content = models.TextField()
In your views.py
# views.py
def post_list(request):
filter_query = request.GET.get('fq')
if filter_query:
posts = BlogPost.objects.filter(post_title__contains=filter_query)
else:
posts = BlogPost.objects.all()
return render(request, 'posts.html', {'posts': posts})
Find users using a specific email address under a specific domain such as @gmail.com or @yahoo.com
Django models:
# in your app models.py
class User(models.Model):
username = models.CharField(max_length=30, unique=True)
email = models.EmailField(unique=True)
Django views:
# views.py
def all_gmail_users(request):
users = User.objects.filter(email__contains='gmail.com')
return render(request, 'gmail_users.html', {'users': users})
def all_yahoo_users(request):
users = User.objects.filter(email__contains='yahoo.com')
return render(request, 'yahoo_users.html', {'users': users})
Retrieve a list of books whose titles contain a certain phrase or keyword
For example, you may wish to search for all the books that are beginner’s guides based on whether they contain the phrase ‘beginner’s guide’ in their titles.
In models.py
# model.py
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='books'
)
In views.py
# views.py
def beginner_guide_books(request):
books = Book.objects.filter(title__icontains="beginner's guide")
return render(request, 'beginner_guide_books.html', {'books': books})
The same implementation goes for searching for all the books that have the ‘subtle art’ or “quick introduction” in their titles.
# views.py
def books(request):
search_query = request.GET.get('q')
if search_query:
books = Book.objects.filter(title__icontains="beginner's guide")
else:
books = Book.objects.all()
return render(request, 'books.html', {'books': books})
Filter movies based on the genre they are on
First, create the Movie model:
# models.py
class Movie(models.Model):
title = models.CharField(max_length=100)
genre = models.CharField(max_length=50)
If you want to filter the movies by genre using the contains
field lookup type, your views.py code should look like this:
def action_movies(request):
genre = request.GET.get('movie_genre')
if genre:
movies = Movie.objects.filter(genre__contains='genre')
else:
movies = Movie.objects.all()
return render(request, 'movies.html', {'movies': movies})
To filter the movies by genre using the contains
lookup type, you can implement that like this:
def action_movies(request):
genre = request.GET.get('movie_genre')
if genre:
movies = Movie.objects.filter(genre__icontains='genre')
else:
movies = Movie.objects.all()
return render(request, 'movies.html', {'movies': movies})
Other applications of contains
and icontains
lookup types in Django include:
- Find resumes in the database that have a certain skill
- Find products with particular phrases in their descriptions
- Find students that have a specific surname or taking a particular subject
- Find events that are associated with particular keywords. For example, you can implement hashtags to sort events that contain the ‘conference’ phrase.
- Find events hosted in particular locations such as cities.