How I Built an English Dictionary App with Django

As we all know, Django is a Python framework used for building complex web applications. Yet, it can also be used for building simple ones. In this tutorial, I’m going to show you πŸ“– how I built an English dictionary app, a simple Django project for beginners.

It takes time for a beginner to fully understand how Django works. But the key is consistency. If you keep building projects, you will gradually know enough to be dangerous with Django.

πŸ‘‡ Scroll to the end to see the full code on GitHub!

A Dictionary App? πŸ“–

A dictionary is an application used to get a particular word’s meaning. No matter how proficient we are in English, some words are far beyond our understanding. There are also words we may not know how to pronounce efficiently, especially those originating from a different language.

Furthermore, we may want to know a synonym or antonym of a given word. This is where a dictionary comes in handy. With a dictionary, we get to know not only the meaning of a word but how it is pronounced, what parts of speech it belongs to, and how it is used in a sentence. Students, no doubt, appreciate the importance of having a dictionary.

How Will We Get The Data?

How will we build this dictionary app so that when users search for a particular word, they get the meaning?

We have two options. Either we use PyDictionary, a Python module and an API that scrapes an online dictionary website or we perform the web scraping ourselves. None of these methods comes without a drawback.

πŸ’‘ Recommended: Is Web Scraping Legal?

The drawback is the challenge that comes with web scraping. Many websites sometimes change their HTML structures to prevent people or bots from accessing their content. So, if an API is not actively maintained, it can quickly become useless. This is the case with PyDictionary. Therefore, we are going to perform web scraping.

Doing so will undoubtedly gain some valuable experience in web scraping, a very broad concept in Python programming. Still, we are at the mercy of website owners. They can change the HTML structures of their websites unexpectedly.


This tutorial assumes you are familiar with Python, HTML, and Bootstrap. If not, please you are required to have at least a basic knowledge before attempting this project. Basic knowledge of Django, though not required, can speed up the learning process.

Getting started

Create a new folder for this project. Then you do the following:

  1. Create a virtual environment
    python3 -m venv .venv
  2. Activate the virtual environment
    source .venv/bin/activate
  3. Install the required libraries in the virtual environment
    pip install django tzdata requests bs4
  4. Create a requirements.txt file to keep a record of the module versions.
    pip freeze > requirements.txt

Creating Django Project and Application

i. Creating the project
django-admin startproject project .
This creates a folder called project in the current directory.

ii. Creating the application
python3 startapp dictionary
The file is an executable file used to run Django commands

iii. Applying migrations
python3 migrate

iv. Checking to see if the installation was successful
python3 runserver

Once you see the above image, you are good to go.

Registering the App

  1. In file
    This step is important whenever an app is created. Navigate to the project folder. Open the file and scroll down to the INSTALLED_APPS section.
   # Application definition

       # custom app

We have registered the app in the file. The file is used to configure the whole project.

  1. In the file
    Open the file in the project folder and add this:
   from django.contrib import admin
   from django.urls import path, include

   urlpatterns = [
       path('', include('dictionary.urls')),

We have registered the app-level URL. Let’s now create it.

Creating the App URL

This will be done inside the dictionary folder. Create a file inside the folder and add this:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.homeView, name='home'),
    path('search', views.searchView, name='search'),

from . import views” tells Django to import the file residing in the dictionary folder.

The empty string indicates the home page URL which is if you are using the local server.

This is where users will be directed when the web page is opened.

For the 'search' string, the URL will be We will be creating two functions in the file as indicated.

Notice the name argument in the path() function, this is another way to refer to the URLs in the template files without using the exact URLs.

Creating Views

In this file, we are going to perform the web scraping we mentioned earlier. The first function, the homeView() is fairly simple. We just render the index.html page once the app is opened.

from django.shortcuts import render
import requests
from bs4 import BeautifulSoup as bs

# Create your views here.

def homeView(request):
    return render(request, 'index.html')

But the searchView() function is a little bit complex. We want to display three things when a user searches for the meaning of a word: meaning, synonyms, and antonyms.

So, we perform web scraping on two online dictionary websites. The first will display the meaning and the second will display the synonyms and antonyms.

def searchView(request):
    word = request.GET['search']

    response = requests.get(f'{word}')
    response2 = requests.get(f'{word}')

    if response:
        soup_1 = bs(response.text, 'html.parser')
        meaning = soup_1.find_all('div', {'value': '1'})
        meaning_1 = meaning[0].getText()
        word = f'Sorry, we couldn\'t find your word {word} in our records.'
        meaning = ''
        meaning_ = ''

    if response2:
        soup_2 = bs(response2.text, 'html.parser')

        synonyms = soup_2.find_all('a', {'class': 'css-1kg1yv8 eh475bn0'})
        synonym_list = []
        for i in range(len(synonyms)):
        antonyms = soup_2.find_all('a', {'class': 'css-15bafsg eh475bn0'})
        antonym_list = []
        for i in range(len(antonyms)):
        synonym_list = ''
        antonym_list = ''

    results = {
        'word': word,
        'meaning': meaning_1,
        'synonyms': synonym_list,
        'antonyms': antonym_list
    return render(request, 'search.html', results)

We import the requests module which uses the get() method to scrape the contents of the two websites.

πŸ’‘ Recommended: My First Python Get Request

The result is a cruel HTML code staring at you. BeautifulSoup, invaluable for web scraping does its job well to pull the data out of the HTML content. This now makes it possible to search the parsed data.

For our first search using the find_all() method from BeautifulSoup, we want a text wrapped in a div tag with the value 1. This is where the website owners kept the meaning of a particular word on the website.

So, we use the getText() method to get the text.

The second and third searches look similar to the first but instead of a div, we search in a tag. The words were kept in a tag to make it easy for visitors to be redirected to that particular word if they want to find the definition.

Instead of searching for a value, we search for a CSS class. We then append the results to their respective variables. If you are new to web scraping, you may wonder how we know where those particular words reside.

The answer is found in a browser’s developer tools, preferably Chrome Developer Tools. This is the reason I suggest familiarizing yourself with HTML before attempting this project.

Finally, we render the results on the search.html page. Notice the else statements. This is run if the word is not found on the website. Let’s now create the HTML files.

Creating Templates

Create a folder named templates in the current directory (not in the project or app folder). Then go to the file to let Django know of this development. In the file, import the os module. Then scroll to the TEMPLATES section and add this:

        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], # add these
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [

Then create three files in the templates folder:

  • base.html,
  • index.html, and
  • search.html.

The main HTML files will inherit from the base.html file. Open the base.html file and add the following:

<!DOCTYPE html>
<html lang="en">

    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dictionary App</title>
    <!-- CSS only -->
    <!-- we are getting bootstrap5 from the CDN -->
    <link href="" rel="stylesheet">

    <div class="container mt-4">
        <div class="row">

            <div class="mt-4 p-5 bg-success text-white rounded mb-3">
                <h1>Django English Dictionary</h1>

            <div class="col-md-12">
                {% block content %}
                <!-- here we will inject the content of every page that 
                    inherits from the base page -->
                {% endblock %}


Then, in the index.html add the following:

<!-- the index page is inheriting from the base page -->
<!-- the extends tags are used for inheriting from the base page -->
{% extends 'base.html' %}

<!-- the block content tags for containing content of the page -->
{%  block content %}

<form action="search">
    <div class="input-group">
        <input type="text" required class="form-control" name="search" placeholder="Search your favorite word.......">
        <div class="input-group-append">
            <button class="btn btn-success" type="submit">


{% endblock %}

Recall in the searchView() function, we send a GET request to get the word input by our user from a form that bears the name 'search.' Can you now see it in the form?

There will be a problem if you use it otherwise. Finally, add the following to the search.html file.

<!-- SEARCH.HTML -->
{% extends 'base.html' %}
{% block content %}
    <h2 align="center"> {{ word | title }} </h2>
        <b>Meaning: </b>{{meaning}}
    <b>Synonyms: </b>

   {{ synonyms }}
    <b>Antonyms: </b>
     {{ antonyms }}


<p><a href="{% url 'home' %}>Home</a></p>

{% endblock %}

We use Django templating language to render the results of the searchView() function to the HTML. Alright, we are done. Run the server once again and you should see something similar to the images below.

That is the index.html web page. Once you search for a word, the search.html page is displayed as you can see below.

Do you see how each of the pages inherits everything in the base.html file?


We have successfully come to the end of this project. I strongly believe you have learned a lot of things you can apply to your projects. If certain things aren’t clear you may wish to read other project articles.

The full code can be found on my GitHub page Have a wonderful day.

πŸ’‘ Recommended: How I Built a Weather App Using Three Python Frameworks