9 - 点餐应用
主要内容:
bootstrap
账户管理
image.png
本文最新版本
bootstrap
Bootstrap 是来自 Twitter 的开源框架, 它提供了用户界面组件以创造简洁并有吸引力的网页并兼容所有现在的网络浏览器. 参考资料: bootstrap https://baike.so.com/doc/5866541-7589096.html 主页 http://getbootstrap.com/ 入门 https://getbootstrap.com/docs/3.3/getting-started/ 组件 https://getbootstrap.com/docs/3.3/components/
下载, 解压文件到 static.
我们将采用模板
页面自适应:
image.png
账户管理
https://flask-login.readthedocs.org/en/latest/
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 > 技术支持 QQ 群 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)
参考资料
讨论 qq 群 144081101 591302926 567351477 钉钉免费群 21745728
本文涉及的 python 测试开发库 https://github.com/china-testing/python-api-tesing 谢谢点赞!
本文代码地址
本文相关书籍下载
非授权登 6:
image.png
授权登 6:
image.png
来源: http://www.jianshu.com/p/42c647220da1