paint-brush
Flix-Finder: Building a Movie Recommendation App With Django and BrightData [Part 1/3]by@infinity
3,273 reads
3,273 reads

Flix-Finder: Building a Movie Recommendation App With Django and BrightData [Part 1/3]

by Rishabh AgarwalJune 22nd, 2023
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Django application would allow its user to filter movies based on ratings from several rating agencies. We will use BrightData’s services to grab the required data for our application. Let's start building Flix-Finder by installing Django and setting up our Django project.
featured image - Flix-Finder: Building a Movie Recommendation App With Django and BrightData [Part 1/3]
Rishabh Agarwal HackerNoon profile picture

Have you ever struggled to decide which TV show or movie to watch next? Making a decision about your next binge-watch is never easy because there are so many options accessible on different streaming providers.


When deciding on our next movie, we primarily rely on reviews and ratings from several rating agencies (like IMDB). However, choosing which rating to believe in might be difficult given the abundance of these institutions.


Having said that, it is frequently safer to view a movie that has received good marks from a number of these organizations. But isn’t finding such a movie difficult? Yes, it is!


In this three-blog series, we will be creating a software solution to solve this exact problem! This Django application, which we will be calling Flix-Finder, would allow its user to filter movies based on ratings from several rating agencies.


We will use BrightData’s services to grab the required data for our application.


So without further ado, let's start building Flix-Finder.

Setting Up the Application

Before starting with this section, do ensure that Django is installed in your system!


The following command should work if Django is installed in your system.

python3 -m django --version


Use pip to install Django if it is not installed in your system!

python3 -m pip install Django


Let us begin by setting up our Django project. Create a new project using the following command.


rishabh@my-ubuntu:~/projects$ python3 -m django startproject flix_finder


Change the directory to the newly created project directory flix_finder. Open your favorite code editor here. You should see the following files in this directory automatically created by Django.


rishabh@my-ubuntu:~/projects/flix_finder$ tree .
.
├── flix_finder
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1 directory, 6 files


To know more about these files, refer to this explanation provided by Django.


Try running the Django server and accessing localhost:8000 to ensure that the setup was completed properly!


rishabh@my-ubuntu:~/projects/flix_finder$ python3 manage.py runserver

Creating a New App & Our First View

A Django app (or Django application) refers to a component of a larger Django project that encapsulates an individual feature or functionality. Django apps are reusable and independent components. They consist of models, views, templates, tests, and other files.

All of the recommender logic for our project would reside in an application called recommender. To create this app, run the following command.


rishabh@my-ubuntu:~/projects/flix_finder$ python3 manage.py startapp recommender


The above command will create a new folder named recommender. All of our application’s logic would go inside this folder.


There is one more step remaining before we can say that our application is created successfully. Go ahead and add the name of the newly created app in the INSTALLED_APPS list present under flix_finder/settings.py.


# flix_finder/settings.py

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


With this, we have successfully created our recommender app.


Now, let us create our first view.


In Django, views are Python functions that receive HTTP requests and return HTTP responses. Views play an important role in presenting data to users based on some business logic.


Create a new method under recommender/views.py. This method would serve requests coming through localhost:8000/. For now, this endpoint simply returns a hello message.


from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello From Recommender!")


We have created the view method for handling the request, but we haven’t specified (in our project) which endpoints correspond to this view. We do this in the urls.py files.


Create a new file inside the recommender app, and name it urls.py. Here, we specify this correspondence between the URL and the view method.


from django.urls import path

from . import views

urlpatterns = [
    path("", views.index, name = "index")
]


We now need to make Django aware of this new URL’s file. Update the file flix_finder/urls.py to the following.


from django.urls import path, include

urlpatterns = [
    path('', include("recommender.urls")),
    path('admin/', admin.site.urls),
]


Start your server, if not already, and open localhost:8000 on your browser. You should see the hello message.


Hello message from our Recommender App!


Congratulations, you just completed creating your first view!

Let Us Use Templates…

Let us agree… sending a string as a response is not the coolest of things. We should instead send a proper HTML response. And for this exact purpose, we will be using Django Templates.


Create a directory templates under the recommender director. The name of this newly created folder is special as Django by-default searches for HTML files in the directories named templates.


Create a new file named index.html inside the newly created directory. Inside this file, we will write the HTML that we want to render when users visit localhost:8000.


Since writing HTML is not the main focus here, I will skip explaining that part and you can simply copy the HTML from here.


Here are some of the things that you need to know about this HTML file (or Django template) -


(1) This HTML displays four things on the webpage - Navigation bar, Carousel, Movie Search Form, and Movie Search Results.


(2) It uses the Django template language to allow the use of Python variables directly inside the HTML.


(3) It expects featured_movies variable in the context (data passed to template) and will use it to display the carousel.


(4) It expects the form variable to be filled with a Django Form object and will use it to display the Movie Search Form.


(5) It expects the filtered_movie_list variable and will use it to display the results of search.


(6) It also expects no_result_error variable that indicates if the search resulted in an empty response.


We will also need to add some CSS for styling. Create a directory static under the recommender directory. This folder will hold all the static files.


Create a new file named style.css, and paste the CSS from this URL.


With this, we have all the required HTML and CSS in place. Next, we need to create the Movie Search form.

Creating the Movie Search Form

Since our template requires us to provide a form object, we will need to create one.

Not sure what are Django Forms? Read ChatGPT explain this -

Django forms are a module in the Django framework used to create and work with HTML forms. They provide several advantages over using plain HTML forms:

  • Automatic rendering of HTML. You define a Django form class, and Django renders it as an HTML form.
  • Validation of data. Django forms validate the submitted data and clean it before saving.
  • Binding data to forms. You can bind existing data to a form for displaying to the user for edit.

Create a file named forms.py inside the recommender’s app directory. Add the following code to it.


from django import forms

class MovieSearchForm(forms.Form):
    imdb_rating = forms.DecimalField(min_value=0.1, max_value=9.9, required=True, label='Minimum IMDB Rating')
    release_year = forms.IntegerField(required=True)


What we just did is created a form class for our Movie Search Form. This form will contain two fields as described in the class. If you want to know more about forms, check out this.

Updating the Index View

With all the things required for templates set, now we need to update our view method to use this newly created template.


from .forms import MovieSearchForm

# We use a hard-code list here, we will make it dynamic in subsequent parts
featured_movie_list = [
    {
        "img_src": "https://images.thedirect.com/media/article_full/amazing-spider-man-3-andrew-garfield-movie-mcu.jpg",
        "img_alt": "...",
        "active": True
    },
    {
        "img_src": "https://static1.colliderimages.com/wordpress/wp-content/uploads/2022/11/avatar-the-way-of-water-poster.jpg",
        "img_alt": "...",
        "active": False
    }
]


def index(request):
  context = {
    "featured_movies": featured_movie_list,
    "form": MovieSearchForm()
  }
  return render(request, 'index.html', context)


Start your server, and head to localhost:8000. You should see the following page.


Home page of Flix-Finder


IMDB Data From BrightData

With all of the views, URLs, templates, and forms in place, we can now consider the data that our application will operate on. Our program would require data from multiple rating agencies (IMDB, to begin with).


Unfortunately, there is no well-defined API via which we may retrieve this data. One method for obtaining this information is to create our own scrapers using Python Selenium. However, this would require more work, and not everyone is comfortable with such technologies.


A better solution is to use third-party services like BrightData. BrightData makes it easy to obtain all of this information.


For this 1st part, we will be using a pre-curated IMDB dataset from BrightData. This is one of the many datasets that are available on BrightData. This is how we can get it.


(1) Signup for an account on BrightData.


(2) Either go to brightdata.com/cp/datasets from the browser or open Datasets & WebScraper IDE menu from the left.

Datasets & WebScraper IDE Menu on BrightData

(3) Go to Dataset Marketplace, and search for IMDB media dataset.


(4) Click on View Dataset, and download the sample dataset in CSV format.


Once downloaded, rename the file to IMDB.csv, and place it inside the recommender/static folder. This sample CSV contains 28 IMDB attributes for 1000+ movies. Our application will work on this IMDB dataset for this part.

Updating the Index View to Receive a Form Submission

Let us update the view method to process search requests.


All the search requests from the form arrive as POST requests. After confirming that the form is properly filled, we will list out all the movies from the downloaded CSV file and filter out those that do not match the filter criteria. Here is how the updated code looks.


def index(request):
    if request.method == 'POST':
        form = MovieSearchForm(request.POST)
        if form.is_valid():
            movie_list = _getIMDBMovieDataList()
            filtered_movie_list = _filter_imdb_movie_list(movie_list, form)
            context = {
                "featured_movies": featured_movie_list,
                "form": MovieSearchForm(),
                "filtered_movie_list": filtered_movie_list,
                "no_result_error": len(filtered_movie_list)==0
            }
            return render(request, 'index.html', context)
    context = {
        "featured_movies": featured_movie_list,
        "form": MovieSearchForm()
    }
    return render(request, 'index.html', context)


The implementation of the methods _getIMDBMovieDataList and _filter_imdb_movie_list is nothing specific to Django and is just pure Python. I thus skip talking about that here. The entire views.py file can be found here.

Final Product

Congratulations on reaching this point. If you have followed all steps properly, you should be able to run the server and perform searches through UI. Here is how the search results would look.


Web page showing search result for Minimum IMDB Rating 8.0 and Release Year 2022.


Code For This Series

All code created as a part of this series will be available on this GitHub repository. The final result of this part is contained in this branch named Part1.


It is always a good idea to cross-check your code with the one present on the repo to check if something is wrong.


Concluding Remarks

With this, we come to the end of the first part of this three-part series. In the next part, we will use BrightData’s WebScraper IDE to collect data from other rating agencies. We will then update our form, thus allowing users to perform more complex searches.


We will also be making the Carousel component dynamic!


See you next time… Till then, Happy Learning! 🙂