Goal: What we’ll Build

Have you ever seen websites that compile lists of their top favourite movies of all time?

e.g.

British Film Institute: https://www2.bfi.org.uk/greatest-films-all-time

Empire: https://www.empireonline.com/movies/features/best-movies-2/

New York Times: https://www.imdb.com/list/ls058705802/

In fact, there are companies who have built their entire business around helping people build lists of their favourite things.

e.g.

https://www.listchallenges.com/

Today, we're going to build a website just like that using Flask/WTForms/SQLite/SQLAlchemy and more. It will allow us to create a beautiful website that lists our top 10 films of all time. As we watch more movies, we can always update our list and keep track of which movies to recommend people.

Download the Starting Project

  1. Download the starting .zip files from this lesson's resources (Starting Files - movie-project-start.zip)

  2. Unzip and open the project in PyCharm.

  3. Make sure that the required packages (imports) are all installed and there are no red underlines.

Requirement 1 - Be Able to View Movie List items

we're going to build a website just like that using Flask/WTForms/SQLite/SQLAlchemy and more. It will allow us to create a beautiful website that lists our top 10 films of all time. As we watch more movies, we can always update our list and keep track of which movies to recommend people

from flask import Flask, render_template, redirect, url_for, request
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
import requests

app = Flask(__name__)
app.app_context().push()
app.config['SECRET_KEY'] = '8BYkEfBA6O6donzWlSihBXox7C0sKR6b'
Bootstrap(app)

#use this: app.app_context().push() after line app = Flask(name) to fix below mentioned RuntimeError:
"""
## TODO: This typically means that you attempted to use functionality that needed the current application. To solve this, set up an application context with app.app_context(). See the documentation for more information.
"""

##CREATE DATABASE
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///new-books-collection.db"
#Optional: But it will silence the deprecation warning in the console.
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Movie(db.Model):
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(250), unique=True, nullable=False)
    year = db.Column(db.String(250), nullable=False)
    description = db.Column(db.String(250), nullable=False)
    rating = db.Column(db.Float, nullable=False)
    ranking = db.Column(db.Float, nullable=False)
    review = db.Column(db.String(250), nullable=False)
    img_url = db.Column(db.String(250), nullable=False)

    def __repr__(self):
        return f'<Movie {self.title} {self.year} {self.description} {self.rating} {self.ranking} {self.review} {self.img_url}>'
    
db.create_all()

#CREATE RECORD
"""
new_movie = Movie(
    title="Phone Booth",
    year=2002,
    description="Publicist Stuart Shepard finds himself trapped in a phone booth, pinned down by an extortionist's sniper rifle. Unable to leave or receive outside help, Stuart's negotiation with the caller leads to a jaw-dropping climax.",
    rating=7.3,
    ranking=10,
    review="My favourite character was the caller.",
    img_url="<https://image.tmdb.org/t/p/w500/tjrX2oWRCM3Tvarz38zlZM7Uc10.jpg>"
)
db.session.add(new_movie)
db.session.commit()
"""

@app.route("/")
def home():
    movie = Movie.query.filter_by(id=1).first()
    print(movie)
    return render_template("index.html",new_movie=movie)

if __name__ == '__main__':
    app.run(debug=True)
{% extends 'bootstrap/base.html' %}

{% block styles %}
  {{ super() }}
  <link rel="stylesheet" href="<https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,700>">
  <link rel="stylesheet" href="<https://fonts.googleapis.com/css?family=Poppins:300,400,700>">
    <link rel="stylesheet" href="<https://fonts.googleapis.com/css?family=Poppins:300,400,700>">
    <link rel="stylesheet" href="<https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css>" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
  <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
{% endblock %}

{% block title %}My Top 10 Movies{% endblock %}

{% block content %}
<div class="container">
  <h1 class="heading">My Top 10 Movies</h1>
  <p class="description">These are my all time favourite movies.</p>
   
  <div class="card" >
    <div class="front" style="background-image: url(' {{new_movie.img_url}} ');">
        <p class="large">{{ new_movie.ranking }}</p>
    </div>
    <div class="back">
      <div>
    <div class="title">{{new_movie.title}} <span class="release_date">({{new_movie.year}})</span></div>
        <div class="rating">
            <label>{{new_movie.rating}}</label>
          <i class="fas fa-star star"></i>
        </div>
          <p class="review">"{{new_movie.review}}"</p>
        <p class="overview">
            {{ new_movie.description }}
        </p>

        <a href="#" class="button">Update</a>
        <a href="#" class="button delete-button">Delete</a>

      </div>
    </div>
  </div>
</div>
<div class="container text-center add">
<a href="#" class="button">Add Movie</a>
</div>

{% endblock %}

Requirement 2 - Be Able to Edit a Movie’s Rating

  1. Use what you have learnt about WTForms to create the RateMovieForm. Use this to create a Quick Form to be rendered in edit.html.

NOTE: You don't need to change the code in edit.html, it already has everything you need to render your Quick Form. This is so that students don't just create a simple HTML form.

If you've forgotten how to work with WTForms, you can go back a few lessons and review the content there or just use the documentation:

https://pythonhosted.org/Flask-Bootstrap/forms.html

https://wtforms.readthedocs.io/en/2.3.x/

https://flask-wtf.readthedocs.io/en/stable/

  1. Once the form is submitted and validated, add the updates to the corresponding movie entry in the database. Here's more documentation on SQLAchemy:

https://flask-sqlalchemy.palletsprojects.com/en/2.x/quickstart/#a-minimal-application

https://pythonhosted.org/Flask-Bootstrap/forms.html

https://wtforms.readthedocs.io/en/2.3.x/

https://flask-wtf.readthedocs.io/en/stable/