Personal Catalogue: Django & PostgreSQL — Chapter 7, Exercise 2 ==================================================== TASK Switch to the PostgreSQL full-text search version, add an item titled "Learning Python Programming", and confirm a search for "programmer" (not "programming") still finds it — then explain why icontains alone would not have. SOLUTION 1. Add 'django.contrib.postgres' to INSTALLED_APPS in settings.py. 2. Replace the search portion of get_queryset() with the full-text search version from the chapter: from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank query = self.request.GET.get('q') if query: search_query = SearchQuery(query) queryset = queryset.annotate( search=SearchVector('title', 'creator'), rank=SearchRank(SearchVector('title', 'creator'), search_query), ).filter(search=search_query).order_by('-rank') 3. Add a real item titled "Learning Python Programming" (any creator, any item type - a book fits the title naturally). 4. Search for "programmer" via /?q=programmer. The item should appear in the results, even though its actual stored title contains "Programming", not "programmer". WHY icontains WOULD NOT HAVE FOUND IT title__icontains='programmer' performs a literal substring match - it checks whether the exact character sequence "programmer" appears anywhere inside the title field, ignoring case. The stored title is "Learning Python Programming" - the substring "programmer" (with an "er" ending) genuinely does not appear anywhere inside "Programming" (with an "ing" ending), so a plain icontains lookup would correctly, but unhelpfully, report no match. WHY POSTGRESQL FULL-TEXT SEARCH DOES FIND IT PostgreSQL's full-text search doesn't match raw substrings - it applies real linguistic stemming, reducing words to a common root form before comparing. Both "programming" and "programmer" stem from the same root ("program"), so PostgreSQL's search engine recognizes them as related forms of the same underlying word and matches the query against the stored title despite the literal spellings being different. ANSWER: icontains performs a literal substring match, and the exact character sequence "programmer" does not appear inside the stored word "Programming" - so it correctly finds no match. PostgreSQL's full-text search instead reduces both words to a shared linguistic root through stemming, recognizing "programmer" and "programming" as related forms of the same underlying word, which is why only the full-text search version successfully finds the item. WHY THIS WORKS AS AN ANSWER ---------------------------- It uses a real, specific word pair to demonstrate the exact linguistic distinction (a differing suffix that breaks substring matching but not stemming-based matching), rather than asserting the two search methods differ without showing a concrete case where the difference actually matters.