forked from techwithtim/Flask-Web-App-Tutorial
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2bc2de9
Showing
13 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.vscode | ||
website/__pycache__ | ||
website/database.db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Flask Web App Tutorial | ||
|
||
## Setup & Installtion | ||
|
||
Make sure you have the latest version of pythin installed. | ||
|
||
```bash | ||
git clone <repo-url> | ||
``` | ||
|
||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
|
||
## Running The App | ||
|
||
```bash | ||
python main.py | ||
``` | ||
|
||
## Viewing The App | ||
|
||
Go to `http://127.0.0.1:5000` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from website import create_app | ||
|
||
app = create_app() | ||
|
||
if __name__ == '__main__': | ||
app.run(debug=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
flask | ||
Flask-SQLAlchemy | ||
flask-login |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from flask import Flask | ||
from flask_sqlalchemy import SQLAlchemy | ||
from os import path | ||
from flask_login import LoginManager | ||
|
||
db = SQLAlchemy() | ||
DB_NAME = "database.db" | ||
|
||
|
||
def create_app(): | ||
app = Flask(__name__) | ||
app.config['SECRET_KEY'] = 'hjshjhdjah kjshkjdhjs' | ||
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}' | ||
db.init_app(app) | ||
|
||
from .views import views | ||
from .auth import auth | ||
|
||
app.register_blueprint(views, url_prefix='/') | ||
app.register_blueprint(auth, url_prefix='/') | ||
|
||
from .models import User, Note | ||
|
||
create_database(app) | ||
|
||
login_manager = LoginManager() | ||
login_manager.login_view = 'auth.login' | ||
login_manager.init_app(app) | ||
|
||
@login_manager.user_loader | ||
def load_user(id): | ||
return User.query.get(int(id)) | ||
|
||
return app | ||
|
||
|
||
def create_database(app): | ||
if not path.exists('website/' + DB_NAME): | ||
db.create_all(app=app) | ||
print('Created Database!') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
from flask import Blueprint, render_template, request, flash, redirect, url_for | ||
from .models import User | ||
from werkzeug.security import generate_password_hash, check_password_hash | ||
from . import db | ||
from flask_login import login_user, login_required, logout_user, current_user | ||
|
||
|
||
auth = Blueprint('auth', __name__) | ||
|
||
|
||
@auth.route('/login', methods=['GET', 'POST']) | ||
def login(): | ||
if request.method == 'POST': | ||
email = request.form.get('email') | ||
password = request.form.get('password') | ||
|
||
user = User.query.filter_by(email=email).first() | ||
if user: | ||
if check_password_hash(user.password, password): | ||
flash('Logged in successfully!', category='success') | ||
login_user(user, remember=True) | ||
return redirect(url_for('views.home')) | ||
else: | ||
flash('Incorrect password, try again.', category='error') | ||
else: | ||
flash('Email does not exist.', category='error') | ||
|
||
return render_template("login.html", user=current_user) | ||
|
||
|
||
@auth.route('/logout') | ||
@login_required | ||
def logout(): | ||
logout_user() | ||
return redirect(url_for('auth.login')) | ||
|
||
|
||
@auth.route('/sign-up', methods=['GET', 'POST']) | ||
def sign_up(): | ||
if request.method == 'POST': | ||
email = request.form.get('email') | ||
first_name = request.form.get('firstName') | ||
password1 = request.form.get('password1') | ||
password2 = request.form.get('password2') | ||
|
||
user = User.query.filter_by(email=email).first() | ||
if user: | ||
flash('Email already exists.', category='error') | ||
elif len(email) < 4: | ||
flash('Email must be greater than 3 characters.', category='error') | ||
elif len(first_name) < 2: | ||
flash('First name must be greater than 1 character.', category='error') | ||
elif password1 != password2: | ||
flash('Passwords don\'t match.', category='error') | ||
elif len(password1) < 7: | ||
flash('Password must be at least 7 characters.', category='error') | ||
else: | ||
new_user = User(email=email, first_name=first_name, password=generate_password_hash( | ||
password1, method='sha256')) | ||
db.session.add(new_user) | ||
db.session.commit() | ||
login_user(user, remember=True) | ||
flash('Account created!', category='success') | ||
return redirect(url_for('views.home')) | ||
|
||
return render_template("sign_up.html", user=current_user) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from . import db | ||
from flask_login import UserMixin | ||
from sqlalchemy.sql import func | ||
|
||
|
||
class Note(db.Model): | ||
id = db.Column(db.Integer, primary_key=True) | ||
data = db.Column(db.String(10000)) | ||
date = db.Column(db.DateTime(timezone=True), default=func.now()) | ||
user_id = db.Column(db.Integer, db.ForeignKey('user.id')) | ||
|
||
|
||
class User(db.Model, UserMixin): | ||
id = db.Column(db.Integer, primary_key=True) | ||
email = db.Column(db.String(150), unique=True) | ||
password = db.Column(db.String(150)) | ||
first_name = db.Column(db.String(150)) | ||
notes = db.relationship('Note') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
function deleteNote(noteId) { | ||
fetch("/delete-note", { | ||
method: "POST", | ||
body: JSON.stringify({ noteId: noteId }), | ||
}).then((_res) => { | ||
window.location.href = "/"; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<link | ||
rel="stylesheet" | ||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" | ||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" | ||
crossorigin="anonymous" | ||
/> | ||
<link | ||
rel="stylesheet" | ||
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" | ||
crossorigin="anonymous" | ||
/> | ||
|
||
<title>{% block title %}Home{% endblock %}</title> | ||
</head> | ||
<body> | ||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> | ||
<button | ||
class="navbar-toggler" | ||
type="button" | ||
data-toggle="collapse" | ||
data-target="#navbar" | ||
> | ||
<span class="navbar-toggler-icon"></span> | ||
</button> | ||
<div class="collapse navbar-collapse" id="navbar"> | ||
<div class="navbar-nav"> | ||
{% if user.is_authenticated %} | ||
<a class="nav-item nav-link" id="home" href="/">Home</a> | ||
<a class="nav-item nav-link" id="logout" href="/logout">Logout</a> | ||
{% else %} | ||
<a class="nav-item nav-link" id="login" href="/login">Login</a> | ||
<a class="nav-item nav-link" id="signUp" href="/sign-up">Sign Up</a> | ||
{% endif %} | ||
</div> | ||
</div> | ||
</nav> | ||
|
||
{% with messages = get_flashed_messages(with_categories=true) %} {% if | ||
messages %} {% for category, message in messages %} {% if category == | ||
'error' %} | ||
<div class="alert alert-danger alter-dismissable fade show" role="alert"> | ||
{{ message }} | ||
<button type="button" class="close" data-dismiss="alert"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
{% else %} | ||
<div class="alert alert-success alter-dismissable fade show" role="alert"> | ||
{{ message }} | ||
<button type="button" class="close" data-dismiss="alert"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
{% endif %} {% endfor %} {% endif %} {% endwith %} | ||
|
||
<div class="container">{% block content %} {% endblock %}</div> | ||
<script | ||
src="https://code.jquery.com/jquery-3.2.1.slim.min.js" | ||
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" | ||
crossorigin="anonymous" | ||
></script> | ||
<script | ||
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" | ||
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" | ||
crossorigin="anonymous" | ||
></script> | ||
<script | ||
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" | ||
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" | ||
crossorigin="anonymous" | ||
></script> | ||
|
||
<script | ||
type="text/javascript" | ||
src="{{ url_for('static', filename='index.js') }}" | ||
></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{% extends "base.html" %} {% block title %}Home{% endblock %} {% block content | ||
%} | ||
<h1 align="center">Notes</h1> | ||
<ul class="list-group list-group-flush" id="notes"> | ||
{% for note in user.notes %} | ||
<li class="list-group-item"> | ||
{{ note.data }} | ||
<button type="button" class="close" onClick="deleteNote({{ note.id }})"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</li> | ||
{% endfor %} | ||
</ul> | ||
<form method="POST"> | ||
<textarea name="note" id="note" class="form-control"></textarea> | ||
<br /> | ||
<div align="center"> | ||
<button type="submit" class="btn btn-primary">Add Note</button> | ||
</div> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{% extends "base.html" %} {% block title %}Login{% endblock %} {% block content | ||
%} | ||
<form method="POST"> | ||
<h3 align="center">Login</h3> | ||
<div class="form-group"> | ||
<label for="email">Email Address</label> | ||
<input | ||
type="email" | ||
class="form-control" | ||
id="email" | ||
name="email" | ||
placeholder="Enter email" | ||
/> | ||
</div> | ||
<div class="form-group"> | ||
<label for="password">Password</label> | ||
<input | ||
type="password" | ||
class="form-control" | ||
id="password" | ||
name="password" | ||
placeholder="Enter password" | ||
/> | ||
</div> | ||
<br /> | ||
<button type="submit" class="btn btn-primary">Login</button> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{% extends "base.html" %} {% block title %}Sign Up{% endblock %} {% block | ||
content %} | ||
<form method="POST"> | ||
<h3 align="center">Sign Up</h3> | ||
<div class="form-group"> | ||
<label for="email">Email Address</label> | ||
<input | ||
type="email" | ||
class="form-control" | ||
id="email" | ||
name="email" | ||
placeholder="Enter email" | ||
/> | ||
</div> | ||
<div class="form-group"> | ||
<label for="firstName">First Name</label> | ||
<input | ||
type="text" | ||
class="form-control" | ||
id="firstName" | ||
name="firstName" | ||
placeholder="Enter first name" | ||
/> | ||
</div> | ||
<div class="form-group"> | ||
<label for="password1">Password</label> | ||
<input | ||
type="password" | ||
class="form-control" | ||
id="password1" | ||
name="password1" | ||
placeholder="Enter password" | ||
/> | ||
</div> | ||
<div class="form-group"> | ||
<label for="password2">Password (Confirm)</label> | ||
<input | ||
type="password" | ||
class="form-control" | ||
id="password2" | ||
name="password2" | ||
placeholder="Confirm password" | ||
/> | ||
</div> | ||
<br /> | ||
<button type="submit" class="btn btn-primary">Submit</button> | ||
</form> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from flask import Blueprint, render_template, request, flash, jsonify | ||
from flask_login import login_required, current_user | ||
from .models import Note | ||
from . import db | ||
import json | ||
|
||
views = Blueprint('views', __name__) | ||
|
||
|
||
@views.route('/', methods=['GET', 'POST']) | ||
@login_required | ||
def home(): | ||
if request.method == 'POST': | ||
note = request.form.get('note') | ||
|
||
if len(note) < 1: | ||
flash('Note is too short!', category='error') | ||
else: | ||
new_note = Note(data=note, user_id=current_user.id) | ||
db.session.add(new_note) | ||
db.session.commit() | ||
flash('Note added!', category='success') | ||
|
||
return render_template("home.html", user=current_user) | ||
|
||
|
||
@views.route('/delete-note', methods=['POST']) | ||
def delete_note(): | ||
note = json.loads(request.data) | ||
noteId = note['noteId'] | ||
note = Note.query.get(noteId) | ||
if note: | ||
if note.user_id == current_user.id: | ||
db.session.delete(note) | ||
db.session.commit() | ||
|
||
return jsonify({}) |