上一讲,我们讲解了如何部署报修小程序后台 flask 项目,如果你还没有安装部署成功 , 请在公众号里留言 ,我会指导你安装部署完成 。
通过本讲,你将学会 flask 路由的使用、熟悉后台管理 flask 启动程序的详细内容 。
路由:是使用 route() 装饰器把函数绑定到指定的 URL ,通过访问此 URL 即可执行 route() 装饰函数里的代码块 , 进而完成相关业务逻辑、访问 html 模版、返回 json 数据等。
flask 后台管理程序中 ,我们使用的启动程序是 app.py , app.py 中包含四个路由,分别是:login、logout、home、api/signIn ,这四个路由完成了后台管理的登录、登出、主页的功能。
1、login 路由 ,用户登录页面展示,整个函数的作用是:访问 http://127.0.0.1:5000/login 跳转到后台管理用户登录页面 ,仅仅是页面路由并涉及登录的操作。
# 用户登录view
@app.route('/login')
def login():
return render_template("/login.html")
详细讲解:
@app.route('/login') 就是一个用户登录的路由 , 为什么是app.route()呢?因为上文中有这样一句话:app = Flask(name) ,也就是 flask 主程序的名字定义为 app ,所以在启动程序中路由均使用 @app.route() 。
那么问题来了?必须是 app.route() 吗 ? 当然不是了 , 你可以使用任何你想要使用名字 ,比如你可以使用 myApp ,定义 myApp = Flask(name) ,而路由相应的需要使用 myApp.route() 。
login 是路由的名字,定义了 @app.route('/login') 后 ,启动 flask 主程序 ,我们就可以通过网站:http://127.0.0.1:5000/login 访问到路由 login。
def login() 不用讲,就是定义了一个无参数的普通函数 。
render_template("/login.html") :render_template 是Jinja2 模板引擎的一个函数 ,这里他的作用是:将模版目录 templates 下的 login.html 渲染展示出来。
2、logout 路由 , 用户登出操作 ,整个函数的作用是退出当前登录的用户 , 并指向登录页面,即回到登录页面。
# 退出登录view
@app.route('/logout')
def logout():
del session['username']
return render_template("/login.html")
详细讲解:
del session'username' ,退出登录的操作 ,作用是:删除 session 中 username 字段 , 即删除用户登录保存的信息 。
为什么用户退出登录要删除 session 中的 username 信息呢?因为我们在用户输入账号密码正确后 , 向 session 中写入了 username ,做为用户登录的依据 , session 中 username 字段为空 , 则说明用户未登录或已经退出 。 session 的来源请看下面的 api/signIn 路由讲解 。
3、home 路由 , 用户登录后的后台主页展示 , 作用是:用户登录后 ,通过访问 http://127.0.0.1:5000/home 即可访问主页内容 。
# 后台主页view
@app.route('/home')
def home():
return render_template('/home.html', userName=session.get("username"))
详细讲解:
render_template('/home.html',userName=session.get("username")) :使用 render_template 函数将 templates 的 home.html 展示出来 ,同时后面携带了一个参数 userName ,userName 的值是从 session 中获取的 username 的值 。而 home.html 中就可以通过 Jinja2 模版引擎的标签语言 {{ userName }} 将登录用户的用户名展示到页面中 。
4、api/signIn 路由 , 用户登录请求数据库的接口 ,作用是:通过前台 ajax 传递过来的用户名和密码 , 查询数据库 user 表 ,若存在此用户并且用户名正确 ,则登录成功 , 否则登录失败 ,返回的数据格式是 json 字符串 。
# 用户登录接口
@app.route('/api/signIn', methods=['POST'])
def signIn():
# 从request对象中读取表单内容:
username = request.form['username']
password = request.form['password']
userResult = User.query.filter(User.userName == username).first() # 简单查询 使用关键字实参的形式来设置字段名
if userResult is not None:
a = hashlib.md5()
a.update(password.encode(encoding="utf-8"))
md5Password = a.hexdigest() # sha1哈希加密
if md5Password == userResult.userPassword:
session['username'] = userResult.userName
return jsonify({'status': 200, 'errmsg': '登录成功!'})
return jsonify({'status': 500, 'errmsg': '用户密码错误,请输入正确的密码!'})
return jsonify({'status': 500, 'errmsg': '登录失败,用户不存在!'})
详细讲解:
@app.route('/api/signIn', methods='POST') :这里我们会发现路由多了一个参数 methods ,methods 是干嘛的呢 ? 为什么上面三个路由都没有指定 methods ?
methods 是指路由请求的方式 ,指定 methods='POST' 后 , 表示此路由仅仅支持 http POST 请求 ,而上面三个没有指定 methods 是因为 flask 路由默认是 GET 请求,即:methods='GET' ,仅仅支持 http GET 请求 。
那么如果我们想让一个路由即支持 GET 又支持 POST 怎么写呢?只需要指定 methods='GET','POST' ,即改为:@app.route('/api/signIn', methods='POST','GET') 就可支持两种请求方式 。
username = request.form['username']
password = request.form['password']
这两行代码的作用是:从请求中获取 form 表单中的用户名和密码 , 即用户登录时输入的用户名和密码 。request.form :根据名字获取请求表单里的内容 。
userResult = User.query.filter(User.userName == username).first()
User.query.filter 是查询数据中 userName 等于从表单中获取的用户名 ,flask 如何操作数据库 , 后面我们详细讲解 。
if userResult is not None:
a = hashlib.md5()
a.update(password.encode(encoding="utf-8"))
md5Password = a.hexdigest() # sha1哈希加密
if md5Password == userResult.userPassword:
session['username'] = userResult.userName
return jsonify({'status': 200, 'errmsg': '登录成功!'})
return jsonify({'status': 500, 'errmsg': '用户密码错误,请输入正确的密码!'})
return jsonify({'status': 500, 'errmsg': '登录失败,用户不存在!'})
此段代码即用户登录逻辑判断 , 首先是判断是否从数据库中查询到了该用户,若没有查询到即:if userResult is None 返回 json 字符串 return jsonify({'status': 500, 'errmsg': '登录失败,用户不存在!'}) ,jsonify 的作用是将一个字典转换为 json 字符串返回给前台 ajax 请求 。若查询到用户 ,判断密码是否匹配 ,数据库中密码是md5加密保存的,这里将表单中的密码 md5 加密后与数据库查询出来的密码对比 , 相等则登录成功 , 不相等则登录失败 。
通过这一讲:你应该明白如何定义路由 , 如何将路由指向具体的页面 ,如何使用指定 GET、POST 请求 。同时对报修小程序后台源码进一步理解,为看懂源码并扩展后台功能做准备。
对此,你有什么疑问呢?欢迎到公众号【JeenWang】留言 ,我会第一时间为你解答 !
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。