What is the difference between contains and icontains in Django?

Share your love

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?

  1. contains and icontains can only be used for filtering data and cannot be used to update or delete records in your database.
  2. contains and icontains implementation only works as Django code. Thus, you cannot use contains and icontains as code implementation for your SQL query statements. If you wish to write the SQL queries, you need to use the LIKE and ILIKE operator equivalents.
  3. contains and icontains 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 with contains and icontains 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:

  1. Find resumes in the database that have a certain skill
  2. Find products with particular phrases in their descriptions
  3. Find students that have a specific surname or taking a particular subject
  4. Find events that are associated with particular keywords. For example, you can implement hashtags to sort events that contain the ‘conference’ phrase.
  5. Find events hosted in particular locations such as cities.
Share your love
Badi
Badi

Badi here, creator of ngangasn.com— A website dedicated to providing helpful information and how-to's of web development and hosting. Inspired by a fascination to write the most efficient code to make a computer laugh, & humans, Steve has a passion for organizing characters to create code and informative content.
What makes me happy?
Well, nothing like the feeling of finally figuring out that one pesky bug that's been driving me crazy.

Leave a Reply

Your email address will not be published. Required fields are marked *