Project 2: Habit Tracker: Using MongoDB in the habit tracker (+40, -21)
.env.example (+1, -0)
From:
curriculum/section10/lectures/09_using_mongodb_in_project/end/.env.example
To:
curriculum/section10/lectures/09_using_mongodb_in_project/end/.env.example
new file mode 100644
index 0000000..9dead41
--- /dev/null
+++ b/curriculum/section10/lectures/09_using_mongodb_in_project/end/.env.example
@@ -0,0 +1 @@
+MONGODB_URI=
app.py (+8, -1)
From:
curriculum/section10/lectures/09_using_mongodb_in_project/start/app.py
To:
curriculum/section10/lectures/09_using_mongodb_in_project/end/app.py
index 8c8ddb0..90af667 100644
--- a/curriculum/section10/lectures/09_using_mongodb_in_project/start/app.py
+++ b/curriculum/section10/lectures/09_using_mongodb_in_project/end/app.py
@@ -1,9 +1,16 @@
+import os
from flask import Flask
from routes import pages
+from pymongo import MongoClient
+from dotenv import load_dotenv
+
+load_dotenv()
def create_app():
app = Flask(__name__)
- app.register_blueprint(pages)
+ client = MongoClient(os.environ.get("MONGODB_URI"))
+ app.db = client.get_default_database()
+ app.register_blueprint(pages)
return app
routes.py (+27, -16)
From:
curriculum/section10/lectures/09_using_mongodb_in_project/start/routes.py
To:
curriculum/section10/lectures/09_using_mongodb_in_project/end/routes.py
index be8e7c6..747b651 100644
--- a/curriculum/section10/lectures/09_using_mongodb_in_project/start/routes.py
+++ b/curriculum/section10/lectures/09_using_mongodb_in_project/end/routes.py
@@ -1,36 +1,45 @@
import datetime
-from collections import defaultdict
-from flask import Blueprint, render_template, request, redirect, url_for
+import uuid
+from flask import Blueprint, request, redirect, url_for, render_template, current_app
pages = Blueprint(
"habits", __name__, template_folder="templates", static_folder="static"
)
-habits = ["Test habit"]
-completions = defaultdict(list)
@pages.context_processor
def add_calc_date_range():
- def date_range(start: datetime.date):
+ def date_range(start: datetime.datetime):
dates = [start + datetime.timedelta(days=diff) for diff in range(-3, 4)]
return dates
return {"date_range": date_range}
+def today_at_midnight():
+ today = datetime.datetime.today()
+ return datetime.datetime(today.year, today.month, today.day)
+
+
@pages.route("/")
def index():
date_str = request.args.get("date")
if date_str:
- selected_date = datetime.date.fromisoformat(date_str)
+ selected_date = datetime.datetime.fromisoformat(date_str)
else:
- selected_date = datetime.date.today()
+ selected_date = today_at_midnight()
+
+ habits_on_date = current_app.db.habits.find({"added": {"$lte": selected_date}})
+ completions = [
+ habit["habit"]
+ for habit in current_app.db.completions.find({"date": selected_date})
+ ]
return render_template(
"index.html",
- habits=habits,
+ habits=habits_on_date,
selected_date=selected_date,
- completions=completions[selected_date],
+ completions=completions,
title="Habit Tracker - Home",
)
@@ -38,20 +47,22 @@ def index():
@pages.route("/complete", methods=["POST"])
def complete():
date_string = request.form.get("date")
- date = datetime.date.fromisoformat(date_string)
- habit = request.form.get("habitName")
- completions[date].append(habit)
+ date = datetime.datetime.fromisoformat(date_string)
+ habit = request.form.get("habitId")
+ current_app.db.completions.insert_one({"date": date, "habit": habit})
return redirect(url_for(".index", date=date_string))
@pages.route("/add", methods=["GET", "POST"])
def add_habit():
+ today = today_at_midnight()
+
if request.form:
- habits.append(request.form.get("habit"))
+ current_app.db.habits.insert_one(
+ {"_id": uuid.uuid4().hex, "added": today, "name": request.form.get("habit")}
+ )
return render_template(
- "add_habit.html",
- title="Habit Tracker - Add Habit",
- selected_date=datetime.date.today(),
+ "add_habit.html", title="Habit Tracker - Add Habit", selected_date=today
)
index.html (+4, -4)
From:
curriculum/section10/lectures/09_using_mongodb_in_project/start/templates/index.html
To:
curriculum/section10/lectures/09_using_mongodb_in_project/end/templates/index.html
index 81e1478..7ad2953 100644
--- a/curriculum/section10/lectures/09_using_mongodb_in_project/start/templates/index.html
+++ b/curriculum/section10/lectures/09_using_mongodb_in_project/end/templates/index.html
@@ -3,11 +3,11 @@
{% block main_content %}
<section class="habit-list">
{% for habit in habits %}
- {% set completed = habit in completions %}
+ {% set completed = habit["_id"] in completions %}
{% if completed %}
<div class="habit completed">
<p class="habit__name">
- {{ habit }}
+ {{ habit["name"] }}
</p>
<svg class="habit__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
@@ -16,10 +16,10 @@
{% else %}
<div class="habit">
<form method="POST" class="habit__form" action="{{ url_for('habits.complete') }}">
- <input type="hidden" id="habitName" name="habitName" value="{{ habit }}" />
+ <input type="hidden" id="habitId" name="habitId" value="{{ habit['_id'] }}" />
<input type="hidden" id="date" name="date" value="{{ selected_date }}" />
<button type="submit" class="habit__button">
- {{ habit }}
+ {{ habit["name"] }}
</button>
</form>
</div>