9 - ordering application
Main contents:
- bootstrap
- Account management
image.png
The latest version of this article
bootstrap
Bootstrap is an open source framework from Twitter, which provides user interface components to create simple and attractive web pages and is compatible with all current web browsers. reference material: bootstrap wikipedia homepage Introduction assembly
download , extract the file to static.
We will adopt Template
Page adaptation:
image.png
Account management
user.py
class User: def __init__(self, email): self.email = email def get_id(self): return self.email def is_active(self): return True def is_anonymous(self): return False def is_authenticated(self): return True
config.py
test = True
mockdbhelper.py
MOCK_USERS = [{"email": "test@example.com", "salt": "8Fb23mMNHD5Zb8pr2qWA3PE9bH0=", "hashed": "1736f83698df3f8153c1fbd6ce2840f8aace4f200771a46672635374073cc876cf0aa6a31f780e576578f791b5555b50df46303f0c3a7f2d21f91aa1429ac22e"}] class MockDBHelper: def get_user(self, email): user = [x for x in MOCK_USERS if x.get("email") == email] if user: return user[0] return None def add_user(self, email, salt, hashed): MOCK_USERS.append({"email": email, "salt": salt, "hashed": hashed})
passwordhelper.py
import hashlib import os import base64 class PasswordHelper: def get_hash(self, plain): return hashlib.sha512(plain.encode('utf-8')).hexdigest() def get_salt(self): return base64.b64encode(os.urandom(20)) def validate_password(self, plain, salt, expected): return self.get_hash(plain + salt) == expected
home.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Waiter Caller</title> <!-- Bootstrap core CSS --> <link href="static/css/bootstrap.min.css" rel="stylesheet"> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Home</a> </div> <div id="navbar" class="navbar-collapse collapse"> <form class="navbar-form navbar-right" action="/login" method="POST"> <div class="form-group"> <input type="text" name="email" placeholder="Email" class="form-control" autofocus> </div> <div class="form-group"> <input type="password" name="password" placeholder="Password" class="form-control"> </div> <input type="submit" value="Sign in" class="btn btn-success"> </form> </div><!--/.navbar-collapse --> </div> </nav>``` <!-- Main jumbotron for a primary marketing message or call to action --> <div class="jumbotron"> <div class="container"> <h1>Waiter Caller</h1> <p>Your patrons can call their waiter anytime, using only their phone</p> </div> </div> <div class="container"> <!-- Example row of columns --> <div class="row"> <div class="col-md-4"> <h2>Simple</h2> <p>Just print out the URLs and put them on the tables of your restaurant. No specialized hardware required. </p> </div> <div class="col-md-4"> <h2>Cost effective</h2> <p>No need to buy hardware either for your tables or for your kitchen. Management and usage all directly from this page.</p> </div> <div class="col-md-4"> <h2>Register now</h2> <form class="form-horizontal" action="/register" method="POST"> <div class="form-group"> <div class="col-sm-9"> <input type="email" name="email" id="email" placeholder="Email address" class="form-control"> </div> </div> <div class="form-group"> <div class="col-sm-9"> <input type="password" name="password" id="password" placeholder="Password" class="form-control"> </div> </div> <div class="form-group"> <div class="col-sm-9"> <input type="password" name="password2" id="password2" placeholder="Confirm password" class="form-control"> </div> </div> <div class="form-group"> <div class="col-sm-9"> <input type="submit" value="Register" class="btn btn-primary btn-block"> </div> </div> </form> <!-- /form --> </div> </div> <div class="container"> </div> <!-- ./container --> <hr> <footer> <p>Technical support QQ Group 144081101 591302926 567351477</p> </footer> </div> <!-- /container --> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> <script src="static/js/bootstrap.min.js"></script> </body> </html>
waitercaller.py
from flask import Flask from flask import redirect from flask import render_template from flask import request from flask import url_for from flask_login import LoginManager from flask_login import login_required from flask_login import login_user from flask_login import logout_user from mockdbhelper import MockDBHelper as DBHelper from passwordhelper import PasswordHelper from user import User app = Flask(__name__) app.secret_key = 'tPXJY3X37Qybz4QykV+hOyUxVQeEXf1Ao2C8upz+fGQXKsM' login_manager = LoginManager(app) DB = DBHelper() PH = PasswordHelper() @login_manager.user_loader def load_user(user_id): user_password = DB.get_user(user_id) if user_password: return User(user_id) @app.route("/login", methods=["POST"]) def login(): email = request.form.get("email") password = request.form.get("password") stored_user = DB.get_user(email) if stored_user and PH.validate_password(password, stored_user['salt'], stored_user['hashed']): user = User(email) login_user(user, remember=True) return redirect(url_for('account')) return home() @app.route("/register", methods=["POST"]) def register(): email = request.form.get("email") pw1 = request.form.get("password") pw2 = request.form.get("password2") if not pw1 == pw2: return redirect(url_for('home')) if DB.get_user(email): return redirect(url_for('home')) salt = PH.get_salt().decode('utf-8') hashed = PH.get_hash(pw1 + salt) DB.add_user(email, salt, hashed) return redirect(url_for('home')) @app.route("/logout") def logout(): logout_user() return redirect(url_for("home")) @app.route("/") def home(): return render_template("home.html") @app.route("/account") @login_required def account(): return "You are logged in" if __name__ == '__main__': app.run(host='0.0.0.0',port=8000, debug=True)
Reference material
- Discussion on qq group 144081101 591302926 567351477 nail free group 21745728
- python test development library involved in this article Thanks a lot!
- Article code address
- Download related books of this article
Unauthorized login:
image.png
Authorized login:
image.png