文章目录
1.文件结构:2.实现效果:3.使用的可视化工具(工具DB Browser for sqlite下载):4.参考过的文章(一部分代码来自这里):5.主文件.main.py:6.前端文件index.html:7.前端文件login.html:8.前端文件register.html:9.前端文件showinfo.html(消息闪现):1.文件结构:
2.实现效果:
3.使用的可视化工具(工具DB Browser for sqlite下载):
/
注:这个工具也可以不用下载,只要以下方式连接数据库之后也可以使用刚才的界面操作(主要是可视化)。
4.参考过的文章(一部分代码来自这里):
https://b23.tv/fV7TiYd
5.主文件.main.py:
import osimport sqlite3 as litefrom flask_wtf import FlaskFormfrom flask_sqlalchemy import SQLAlchemy#flask-sqlalchemyfrom sqlalchemy import String,Column,Integerfrom werkzeug.security import generate_password_hash,check_password_hashfrom wtforms.validators import ValidationError,DataRequired,Length,EqualTofrom flask import Flask,render_template,redirect,request,url_for,flash,jsonifyfrom wtforms import StringField,SubmitField,TextAreaField,PasswordField,BooleanFieldfrom flask_login import LoginManager,UserMixin,current_user,login_user,logout_user,login_requiredapp=Flask(__name__)#获得当前目录路径# basedir=os.path.abspath(os.path.dirname(__file__))basedir=os.getcwd()tab1_user=basedir+'\\app.db'print(basedir)print(tab1_user)#配置数据库class Config(object):SECRET_KEY='flask_login'SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(basedir,'app.db')SQLALCHEMY_TRACK_MODIFICATIONS=Falseapp.config.from_object(Config)mysql=SQLAlchemy(app)login_manager=LoginManager(app)#创建登录表单类class LoginForm(FlaskForm):username=StringField(label='用户名',validators=[DataRequired()])password=PasswordField(label='密码',validators=[DataRequired()])remember_me=BooleanField(label='记住我')submit=SubmitField(label='登录')#注册表单class RegisgerForm(FlaskForm):username=StringField(label='用户名',validators=[DataRequired()])password=PasswordField(label='设置密码',validators=[DataRequired()])submit=SubmitField(label='注册')#UserMixin: 表示通过认证用户#is_authenticated: 表示用户是否通过登录认证属性,用True和Flase表示#is_active: 表示用户账户是活跃的,那么这个属性是True,否则就是Flase#is_anonymous: 表示常规用户的该属性是Flase ,对特定的用户是Trueclass User(mysql.Model,UserMixin):#定义表名__tablename__='tab_user'id=Column(Integer,primary_key=True)username=Column(String(128),index=True,unique=True)password_hash=Column(String(128),unique=True)# #将密码经过哈希处理,使用密文形式def set_password(self):self.password_hash=generate_password_hash(self.password_hash)#验证密码是否正确#Returns `True` if the password matched, `False` otherwise.def validate_password(self,password):return check_password_hash(self.password_hash,password)#定义输出格式def __repr__(self):return '<User: %s:%s'%(self.id,self.username,self.password_hash)#这个回调用于从会话中存储的用户 ID 重新加载用户对象@login_manager.user_loaderdef load_user(user_id):user=User.query.get(int(user_id))return user#默认情况下,当未登录的用户尝试访问一个 login_required 装饰的视图,# Flask-Login 会闪现一条消息并且重定向到登录视图。(如果未设置登录视图,它将会以 401 错误退出。)login_manager.login_view='login'@app.route('/',methods=['POST','GET'])def index():flash('这是一条闪现消息: 请点击登录/login')return render_template('index.html')@app.route('/login',methods=['POST','GET'])def login():if current_user.is_authenticated:return redirect(url_for('show_user'))form=LoginForm()if request.method=='POST':if form.validate_on_submit():username=form.username.datapassword=form.password.dataremember=form.remember_me.dataprint('username: {}'.format(username))print('password: {}'.format(password))print('remember: {}'.format(remember))#数据库查询user=User.query.filter_by(username=username).first()if user:if username==user.username and user.validate_password(password):# if username==username:#login_user表示让用户登录。保存到当前会话当中(session),这样才能加载和访问idlogin_user(user,remember)flash('登录成功')return redirect(url_for('show_user'))else:flash('账户名或者密码错误')redirect(url_for('login'))return render_template('login.html',form=form)@app.route('/showuser',methods=['POST','GET'])#需要用户登入 的视图可以用 login_required(视图保护) 装饰器来装饰:#如果在设置了视图函数login_manager.login_view='login'(视图函数设置为login表示只有用户在登录的情况下才能正常# 进行访问进行视图保护(@login_required)的页面,否则将重定向到登录视图页面)之后#在不写@login_required语句的情况下使用current_user.username会报错#当未登录的用户尝试访问一个 login_required 装饰的视图,Flask-Login 会闪现一条消息并且重定向到登录视图:例如这里可以尝试访问http://127.0.0.1:5000/showus@login_requireddef show_user():#获得当前登录的用户username=current_user.usernamereturn render_template('index.html',username=username)@app.route('/logout',methods=['POST','GET'])def logout():#Logs a user out. (You do not need to pass the actual user.)# This will also clean up the remember me cookie if it exists.logout_user()return redirect(url_for('login'))#实现注册@app.route('/register',methods=['POST','GET'])def register():registerform=RegisgerForm()if request.method=='POST':if registerform.validate_on_submit():username=registerform.username.datapassword=registerform.password.datauser_data=User.query.filter_by(username=username).first()if user_data:flash('该用户已经存在')return render_template('showinfo.html')else:new_user=User(username=username,password_hash=password)new_user.set_password()mysql.session.add(new_user)mit()mysql.session.close()flash('注册成功')return render_template('showinfo.html')return render_template('register.html',registerform=registerform)if __name__ == '__main__':print('Pycharm')# mysql.init_app(app)#如果下面这句不写的话,会报一下错误sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed:# mysql.drop_all()mysql.create_all()# new_user1=User(username='tom',password_hash='1233t')# new_user1.set_password()# mysql.session.add(new_user1)# mit()# mysql.session.close()app.run(debug=True)
6.前端文件index.html:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><div class="container" align="center"><h3>这是首页</h3>{% with messages=get_flashed_messages() %}{% if messages %}{% for message in messages %}<div><p style="color:red">{{message}}</p></div>{% endfor %}{% endif %}{% endwith %}<li><a>查询登录名路径,登录状态才能查询: /showuser</a></li>{% if current_user.is_authenticated %}<li><a>当前登录用户名: {{username}}</a></li><li><a href="{{url_for('logout')}}">登出</a></li>{% else %}<li><a href="{{url_for('login')}}">登录</a></li>{% endif %}</div></body></html>
7.前端文件login.html:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title><style>a {text-decoration:none;}</style></head><body><div class="container" align="center"><h3>登录页面</h3>{% with messages=get_flashed_messages()%}{% if messages %}{% for message in messages %}<div><p style="color:red">{{message}}</p></div>{% endfor %}{% endif%}{% endwith %}<form action="" method="POST"><!-- {{form.hidden_tag()}}-->{{form.csrf_token()}}<p>{{form.username.label}}<br>{{form.username}}</p><p>{{form.password.label}}<br>{{form.password}}</p><p>{{form.remember_me()}} {{form.remember_me.label}}</p><p>{{form.submit()}} <button><a href="{{url_for('register')}}">注册</a></button></p></form></div></body></html>
8.前端文件register.html:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Rigister</title><style>div {text-align:center;}</style></head><body><div><h3>注册页面</h3>{% with messages=get_flashed_messages() %}{% if messages%}{% for message in messages%}<div><p style="color:red">{{message}}</p></div>{% endfor %}{% endif %}{% endwith %}<form action="" method="POST">{{registerform.csrf_token()}}<p>{{registerform.username.label}}<br>{{registerform.username}}</p><p>{{registerform.password.label}}<br>{{registerform.password}}</p><p>{{registerform.submit()}}</p></form></div></body></html>
9.前端文件showinfo.html(消息闪现):
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>showinfo</title></head><body><div style="text-align:center;font-size:30px;color:#000000;margin-top:200px;">{% with messages=get_flashed_messages() %}{% if messages%}{% for message in messages%}<div><p style="color:#000000">{{message}}</p></div>{% endfor %}{% endif %}{% endwith %}<li><a href="{{url_for('login')}}">登录</a></li></div></body></html>