Project 4: Movie Watchlist: Adding user logins to the movie watchlist (+70, -10)
forms.py (+6, -0)
From:
curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/forms.py
To:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/forms.py
index a54f8b8..a0b572e 100644
--- a/curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/forms.py
+++ b/curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/forms.py
@@ -17,6 +17,12 @@ from wtforms.validators import (
)
+class LoginForm(FlaskForm):
+ email = StringField("Email", validators=[InputRequired(), Email()])
+ password = PasswordField("Password", validators=[InputRequired()])
+ submit = SubmitField("Login")
+
+
class RegisterForm(FlaskForm):
email = StringField("Email", validators=[InputRequired(), Email()])
routes.py (+27, -2)
From:
curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/routes.py
To:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/routes.py
index 10458d2..d615007 100644
--- a/curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/routes.py
+++ b/curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/routes.py
@@ -12,7 +12,7 @@ from flask import (
url_for,
request,
)
-from movie_library.forms import RegisterForm, MovieForm, ExtendedMovieForm
+from movie_library.forms import LoginForm, RegisterForm, MovieForm, ExtendedMovieForm
from movie_library.models import User, Movie
from passlib.hash import pbkdf2_sha256
@@ -52,13 +52,38 @@ def register():
flash("User registered successfully", "success")
- return redirect(url_for(".index"))
+ return redirect(url_for(".login"))
return render_template(
"register.html", title="Movies Watchlist - Register", form=form
)
+@pages.route("/login", methods=["GET", "POST"])
+def login():
+ if session.get("email"):
+ return redirect(url_for(".index"))
+
+ form = LoginForm()
+
+ if form.validate_on_submit():
+ user_data = current_app.db.user.find_one({"email": form.email.data})
+ if not user_data:
+ flash("Login credentials not correct", category="danger")
+ return redirect(url_for(".login"))
+ user = User(**user_data)
+
+ if user and pbkdf2_sha256.verify(form.password.data, user.password):
+ session["user_id"] = user._id
+ session["email"] = user.email
+
+ return redirect(url_for(".index"))
+
+ flash("Login credentials not correct", category="danger")
+
+ return render_template("login.html", title="Movies Watchlist - Login", form=form)
+
+
@pages.route("/add", methods=["GET", "POST"])
def add_movie():
form = MovieForm()
login.html (+34, -0)
From:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/login.html
To:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/login.html
new file mode 100644
index 0000000..ddedfbc
--- /dev/null
+++ b/curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/login.html
@@ -0,0 +1,34 @@
+{% from "macros/fields.html" import render_text_field %}
+
+{% extends "layout.html" %}
+
+{%- block head_content %}
+ <link rel="stylesheet" href="{{ url_for('static', filename='css/forms.css') }}" />
+{% endblock %}
+
+{% block main_content %}
+
+ <form name="login" method="post" novalidate class="form">
+ {% with messages = get_flashed_messages(with_categories=true) %}
+ {%- for category, message in messages %}
+ <span class="form__flash form__flash--{{category}}"> {{ message }}</span>
+ {% endfor %}
+ {% endwith %}
+
+ <div class="form__container">
+ {{ form.hidden_tag() }}
+
+ {{ render_text_field(form.email) }}
+ {{ render_text_field(form.password) }}
+
+ <span class="form__small">
+ Don't have an account? <a href="{{ url_for('pages.register') }}" class="form__link">Register here</a>.
+ </span>
+
+ <div>
+ {{ form.submit(class_="button button--form") }}
+ </div>
+ </div>
+ </form>
+
+{% endblock %}
nav.html (+2, -2)
From:
curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/templates/macros/nav.html
To:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/macros/nav.html
index 116ad0a..a7a9ece 100644
--- a/curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/templates/macros/nav.html
+++ b/curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/macros/nav.html
@@ -11,8 +11,8 @@
<nav class="nav">
{%- if not email %}
<a
- href="#"
- class="nav__link"
+ href="{{ url_for('pages.login') }}"
+ class="nav__link {{ 'nav__link--active' if request.path == url_for('pages.login') }}"
>
<span class="nav__item">Log in</span>
</a>
register.html (+1, -6)
From:
curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/templates/register.html
To:
curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/register.html
index 55c61ad..5e33806 100644
--- a/curriculum/section14/lectures/16_user_login_in_flask_app/start/movie_library/templates/register.html
+++ b/curriculum/section14/lectures/16_user_login_in_flask_app/end/movie_library/templates/register.html
@@ -9,11 +9,6 @@
{% block main_content %}
<form name="register" method="post" novalidate class="form">
- {% with messages = get_flashed_messages(with_categories=true) %}
- {%- for category, message in messages %}
- <span class="form__flash form__flash--{{category}}"> {{ message }}</span>
- {% endfor %}
- {% endwith %}
<div class="form__container">
{{ form.hidden_tag() }}
@@ -22,7 +17,7 @@
{{ render_text_field(form.confirm_password) }}
<span class="form__small">
- Already have an account? <a href="#" class="form__link">Log in here</a>.
+ Already have an account? <a href="{{ url_for('pages.login') }}" class="form__link">Log in here</a>.
</span>
<div>