“Python Flask: 实现用户注册功能”的版本间的差异
(→实现注册功能) |
(→实现注册功能) |
||
第166行: | 第166行: | ||
==实现注册功能== | ==实现注册功能== | ||
+ | ===注册函数register()=== | ||
通过request.method 判断是否提交了表单, | 通过request.method 判断是否提交了表单, | ||
第227行: | 第228行: | ||
你可以在任意视图函数中调用flash()函数发送消息。 | 你可以在任意视图函数中调用flash()函数发送消息。 | ||
+ | ===(注册后跳转的)登录函数login=== | ||
+ | manage.py: | ||
+ | |||
+ | <nowiki> | ||
+ | @app.route('/login', methods=['GET', 'POST']) | ||
+ | def login(): | ||
+ | return '登录成功!' | ||
+ | </nowiki> | ||
===表单文件forms.py=== | ===表单文件forms.py=== | ||
与manage.py同一目录下 | 与manage.py同一目录下 |
2022年1月28日 (五) 07:37的版本
目录
创建注册路由
在manage.py入口文件中,创建一个名为app的Flask实例,
然后用app.route()函数创建路由。
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging from mysql_util import MysqlUtil from passlib.hash import sha256_crypt app = Flask(__name__) # 创建应用 # 用户注册 @app.route('/register', methods=['GET', 'POST']) def register(): form = RegisterForm(request.form) # 实例化表单类 return render_template('register.html', form=form) # 渲染模板板
创建模板文件
创建模板文件
render_template()函数默认查找的模板文件路径"/templates",
在该路径下创建register.html
{% extends 'layout.html' %} {% block body %} <div class="content"> <h1 class="title-center">用户注册</h1> {% from "includes/_formhelpers.html" import render_field %} <form method="POST" action=""> <div class="form-group"> {{render_field(form.email, class_="form-control")}} </div> <div class="form-group"> {{render_field(form.username, class_="form-control")}} </div> <div class="form-group"> {{render_field(form.password, class_="form-control")}} </div> <div class="form-group"> {{render_field(form.confirm, class_="form-control")}} </div> <p><input type="submit" class="btn btn-primary" value="注册"></p> </form> </div> {% endblock %}
创建公共文件
layout.html
在templates目录下创建公共文件layout.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>读书笔记</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/style.css"> <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body> {% include 'includes/_navbar.html' %} <div class="container"> {% include 'includes/_messages.html' %} {% block body %}{% endblock %} </div> {% include 'includes/_footer.html' %} </body> </html>
在templates目录的下 创建子目录includes,并创建文件_navbar.html
<nav class="navbar navbar-default"> <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="/">学习笔记</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/">主页</a></li> <li><a href="/articles">笔记</a></li> <li><a href="/about">关于</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if session.logged_in %} <li><a href="/dashboard">控制台</a></li> <li><a href="/logout">退出</a></li> {% else %} <li><a href="/register">注册</a></li> <li><a href="/login">登录</a></li> {% endif %} </ul> </div><!--/.nav-collapse --> </div> </nav>
includes/_messages.html
在templates目录的子目录includes下,创建文件_messages.html
{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}">{{ message }}</div> {% endfor %} {% endif %} {% endwith %} {% if error %} <div class="alert alert-danger">{{error}}</div> {% endif %} {% if msg %} <div class="alert alert-success">{{msg}}</div> {% endif %}
在templates目录的子目录includes下,创建文件_footer.html
<!-- Footer --> <footer class="page-footer font-small blue" style="margin-top: 50px"> <!-- Copyright --> <div class="footer-copyright text-center py-3"> Copyright ©2007-2019 <a href="http://www.mingrisoft.com">明日科技有限公司</a> All Rights Reserved 吉ICP备10002740号-2 吉公网安备22010202000132 </div> <!-- Copyright --> </footer> <!-- Footer -->
includes/_formhelpers.html
在templates目录的子目录includes下,创建文件_formhelpers.html
在该文件中定义了一个宏render_field
{% macro render_field(field) %} {{ field.label }} {{ field(**kwargs)|safe }} {% if field.errors %} {% for error in field.errors %} <span class="help-inline text-danger">{{ error }}</span> {% endfor %} {% endif %} {% endmacro %}
实现注册功能
注册函数register()
通过request.method 判断是否提交了表单,
然后通过form.validate() 进行字段验证,
获取信息,并加密,
将信息写入数据库
跳转到登陆页面 并显示成功信息
如果注册失败,则显示注册信息。
注意:新增from forms import RegisterForm,ArticleForm 一行应用
manage.py:
from flask import Flask, render_template, flash, redirect, url_for, session, request, logging from mysql_util import MysqlUtil from passlib.hash import sha256_crypt from forms import RegisterForm,ArticleForm app = Flask(__name__) # 创建应用 # 用户注册 @app.route('/register', methods=['GET', 'POST']) def register(): form = RegisterForm(request.form) # 实例化表单类 if request.method == 'POST' and form.validate(): # 如果提交表单,并字段验证通过 # 获取字段内容 email = form.email.data username = form.username.data password = sha256_crypt.encrypt(str(form.password.data)) # 对密码进行加密 db = MysqlUtil() # 实例化数据库操作类 sql = "INSERT INTO users(email,username,password) \ VALUES ('%s', '%s', '%s')" % (email,username,password) # user表中插入记录 db.insert(sql) flash('您已注册成功,请先登录', 'success') # 闪存信息 return redirect(url_for('login')) # 跳转到登录页面 return render_template('register.html', form=form) # 渲染模板 if __name__ == '__main__':#程序入口 app.secret_key='secret123' app.run()#让应用运行在本地服务器上。
flask提供了一个非常有用的flash()函数,它可以用来“闪现”需要提示给用户的消息,比如当用户登录成功后显示“欢迎回来!”。在视图函数调用flash()函数,传入消息内容,flash()函数把消息存储在session中,我们需要在模板中使用全局函数get_flashed_messages()获取消息并将它显示出来。
通过flash()函数发送的消息会存储在session对象中,所以我们需要为程序设置秘钥。可以通过app.secret_key属性或配置变量SECRET_KEY设置。
你可以在任意视图函数中调用flash()函数发送消息。
(注册后跳转的)登录函数login
manage.py:
@app.route('/login', methods=['GET', 'POST']) def login(): return '登录成功!'
表单文件forms.py
与manage.py同一目录下
from wtforms import Form, StringField, TextAreaField, PasswordField from wtforms.validators import DataRequired,Length,Email,EqualTo # Article Form Class class ArticleForm(Form): title = StringField( '标题', validators=[ # DataRequired(message= '标题长度应该在2-30字符之间'), DataRequired(message='长度不少于5个字符'), Length(min=2,max=30) ] ) content = TextAreaField( '内容', validators=[ DataRequired(message='长度不少于5个字符'), Length(min=5) ] ) # Register Form Class class RegisterForm(Form): username = StringField( '用户名', validators=[ DataRequired(message='请输入用户名'), Length(min=2, max=25,message='长度在2-25个字符之间') ] ) email = StringField( '邮箱', validators = [ DataRequired(message="请输入邮箱"), Email(message='请输入正确的邮箱格式') ] ) password = PasswordField( '密码', validators = [ DataRequired(message='密码不能为空'), Length(min=6,max=20,message='长度在6-20个字符之间'), ] ) confirm = PasswordField( '确认密码', validators=[ DataRequired(message='密码不能为空'), Length(min=6, max=20), EqualTo('password', message='2次输入密码不一致') ] )