Implementing search with Django, Elasticsearch, and Vue.js

A step-by-step guide to implementing the search feature

Fatime Selimi
Level Up Coding

--

In this short tutorial, I am going to show an example of how to implement a search feature using Elasticsearch with Django and Vue.js.
In the web application that we will create, users can add new articles by providing a title and the content of the article, and some tags if they want. They can also search for articles from the “Articles list”.

Assuming that you already know what Elasticsearch is and why we need it (since you stumbled upon this article in your searches), I will not go into details of explaining Elasticsearch. In short, Elasticsearch is a database that offers powerful search capabilities such as full-text search, fuzzy text search, etc. We will be using Elasticsearch to power our search feature in this web application. If you’re interested in learning more about Elasticsearch, this would be a good start: https://www.elastic.co/what-is/elasticsearch

The example application would look something like the GIF below. As mentioned above, we can add articles using the “New article” form at the bottom of the page or search for the articles using the search bar.

Search feature using Elasticsearch
Search feature using Elasticsearch

The full code for this example web application can be found in this GitHub repo.

Technologies used:

Docker Desktop
Python

Django
Vue.js
Django REST framework
Elasticsearch
Elasticsearch DSL

We will build our application by following these steps:

  1. Create a new virtual environment
  2. Install Django
  3. Create a new Django project and a new Django application
  4. Create REST API models & create Elasticsearch model
  5. Set up Elasticsearch & Kibana servers using Docker
  6. Implement Django views
  7. Create URLs and use DRF UI to test them
  8. Build templates, add and use Vue.js
  9. Run the application

1.Create a new virtual environment
Let’s start by creating a new virtual environment. By doing this, we will isolate our Django setup on a per-project basis, thus any change that we make to our project will not affect other projects that we might also be developing.

In your terminal, run the commands shown below to create a new directory and change the current directory to the new project directory that we just created.

mkdir elastico-appcd elastico-app

Once we have created and are inside the new directory, we are ready to create our new virtual environment by running this command:

python3 -m venv env

And finally, we need to activate the new virtual environment like this:

source env/bin/activate

2.Install Django
Now we can install our preferred Django version. In this example, we will install Django 3.1.4.

(env) ~/elastico-app$ pip install Django==3.1.4

3.Create a new Django project and a new Django application
Next, let’s create a new Django project. We will call this project django_elasticsearch, and we will create it by running the following:

(env) ~/elastico-app$ django-admin startproject django_elasticsearch(env) ~/elastico-app$ cd django_elasticsearch

Next, we will create a new Django application. We will call this application django_formset_vuejs and we will create it like this:

(env) ~/elastico-app/django_elasticsearch$ python manage.py startapp django_elastico_vuejs

After we have successfully created our new application we have to add it to INSTALLED_APPS inside settings.py file.

Note: We also have to add ‘rest_framework’ in the INSTALLED_APPS. So the INSTALLED_APPS list at this point would look like below:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_elastico_vuejs',
]

And our project tree should look like this:

elastico-app
├── django_elastico_vuejs
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
├── django_elasticsearch
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── env

4. Create API models & Create Elasticsearch model
First, we will need to define REST API models so that we have a clear interface between REST API users and our REST API servers.

Next, we will need to define an Elasticsearch document which we will use to represent the searchable data that we will store in the Elasticsearch.

In this way, both interfaces can evolve separately.

Let’s save the models in a newmodels folder, under django_elastico_vuejs app.

4.1 REST API Models

Model objects:

  • Article()
  • ArticleRequest()
  • SearchArticleRequest()

Model serializers:

  • ArticleSerializer()
  • ArticleRequestSerializer()
  • SearchArticleRequestSerializer()

4.2 Elasticsearch document

Define ArticleDocument() as our Elasticsearch document and initiate it using the init() method.

Note: ArticleDocument inherits from Document class of elasticsearch_dsl library.

And the project tree:

elastico-app
├── django_elastico_vuejs
│ ├── migrations
│ ├── models
│ │ └──api
│ │ ├── __init__.py
│ │ └── models.py
│ │ └──es
│ │ ├── __init__.py
│ │ └── models.py
│ │ └── __init__.py
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
├── django_elasticsearch
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── env

5. Set up Elasticsearch & Kibana servers using Docker
We initiate locally the Elasticsearch database using the Docker Compose tool in order to run the Elasticsearch from a docker image.

In addition, we also use Kibana as a data visualization tool for Elasticsearch, thus we have defined a Kibana container in the Docker Compose script as well.

This is how our docker-compose.yml file looks:

To run this Docker Compose file open your terminal and run this command:

(env) ~/elastico-app$ docker-compose up

Note: Make sure that you have installed Docker Desktop and it is running in your machine before trying to run this command, otherwise you’ll encounter issues executing the script docker-compose.

Kibana dashboard can be accessed from the browser using the port that we defined in the docker-compose file, i.e. 5601. For example, when typing http://localhost:5601/app/kibana#/dev_tools/console in the browser’s search bar we see Kibana’s UI similar to the screenshot below.

6. Implement the views
We’re ready to implement our views in django_elastico_vuejs/views.py and handle our REST API as well as initiate the Elasticsearch database.

Note: We’re using Elasticsearch fuzzy query which returns documents that contain terms similar to the search term, as measured by a Levenshtein edit distance.

7. Create URLs and use DRF UI to test them
We also need to create a new file inside django_elastico_vuejs app called urls.py. The code in urls.py should look like this:

And now we need to include django_elastico_vuejs application’s URLs to our main urls.py projects file.

We can test REST APIs using the DRF interface. For example, if we want to test the article creation REST API, we access it using this url: http://127.0.0.1:8000/api/articles/

8. Build templates, add and use Vue.js
We should first create a directory inside django_elastico_vuejs application with the name templates, and then inside templates directory, we should create another directory with the name of our application, that is django_elastico_vuejs.
Now let’s add two templates, base.html and articles.html, inside django_elastico_vuejs.

Our project tree now looks like this:

elastico-app
├── django_elastico_vuejs
│ ├── migrations
│ ├── models
│ ├── templates
│ │ └──django_elastico_vuejs
│ │ ├── articles.html
│ │ └── base.html
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
├── django_elasticsearch
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── env

In base.html we will put the code for our base template with our styles, scripts, and other mutual things that we would like to share with other templates. This file would look like this:

As you can see we have added Vue.js to our project by just adding its CDN and we can freely use it in the templates that extend base.html template.

And then the code inside the articles.html template would look like this:

9.Run the application
At this point, we have finished implementing our application using the Elasticsearch database with Django and Vue.js and we can start our local web server.

(env) ~/elastico-app$ python manage.py runserver
Search feature using Elasticsearch

Conclusion

I hope that you enjoyed this article and that you can use this sample as a guide to using and implementing a search feature using Elasticsearch with Django REST framework and Vue.js.

--

--