标签:http 图片 nal 目录结构 数据 type mod min alt
通过Flask_Login实现用户验证登录,并通过login_required装饰器来判断用户登录状态来判断是否允许访问视图函数。
运行环境:
python3.5 Flask 0.12.2 Flask_Login 0.4.1 Flask-WTF 0.14.2 PyMySQL 0.8.0 WTForms 2.1 DBUtils 1.2
直接看代码,具体功能有注释
Model/User_model.py
1 #创建一个类,用来通过sql语句查询结果实例化对象用 2 class User_mod(): 3 def __init__(self): 4 self.id=None 5 self.username=None 6 self.task_count=None 7 self.sample_count=None 8 9 def todict(self): 10 return self.__dict__ 11 12 #下面这4个方法是flask_login需要的4个验证方式 13 def is_authenticated(self): 14 return True 15 16 def is_active(self): 17 return True 18 19 def is_anonymous(self): 20 return False 21 22 def get_id(self): 23 return self.id 24 25 # def __repr__(self): 26 # return ‘<User %r>‘ % self.username
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <div class="login-content"> 9 <form class="margin-bottom-0" action="{{ action }}" method="{{ method }}" id="{{ formid }}"> 10 {{ form.hidden_tag() }} 11 <div class="form-group m-b-20"> 12 {{ form.username(class=‘form-control input-lg‘,placeholder = "用户名") }} 13 </div> 14 <div class="form-group m-b-20"> 15 {{ form.password(class=‘form-control input-lg‘,placeholder = "密码") }} 16 </div> 17 <div class="checkbox m-b-20"> 18 <label> 19 {{ form.remember_me() }} 记住我 20 </label> 21 </div> 22 <div class="login-buttons"> 23 <button type="submit" class="btn btn-success btn-block btn-lg">登 录</button> 24 </div> 25 </form> 26 </div> 27 28 29 </body> 30 </html>
User_dal/dal.py
1 import pymysql 2 from DBUtils.PooledDB import PooledDB 3 4 POOL = PooledDB( 5 creator=pymysql, # 使用链接数据库的模块 6 maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数 7 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建 8 maxcached=5, # 链接池中最多闲置的链接,0和None不限制 9 maxshared=3, 10 # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。 11 blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错 12 maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制 13 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] 14 ping=0, 15 # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always 16 host=‘192.168.20.195‘, 17 port=3306, 18 user=‘root‘, 19 password=‘youpassword‘, 20 database=‘mytest‘, 21 charset=‘utf8‘ 22 ) 23 24 25 class SQLHelper(object): 26 27 @staticmethod 28 def fetch_one(sql,args): 29 conn = POOL.connection() #通过连接池链接数据库 30 cursor = conn.cursor() #创建游标 31 cursor.execute(sql, args) #执行sql语句 32 result = cursor.fetchone() #取的sql查询结果 33 conn.close() #关闭链接 34 return result 35 36 @staticmethod 37 def fetch_all(self,sql,args): 38 conn = POOL.connection() 39 cursor = conn.cursor() 40 cursor.execute(sql, args) 41 result = cursor.fetchone() 42 conn.close() 43 return result
1 from Model import User_model 2 from User_dal import dal 3 from User_dal import user_dal 4 class User_Dal: 5 persist = None 6 7 #通过用户名及密码查询用户对象 8 @classmethod 9 def login_auth(cls,username,password): 10 print(‘login_auth‘) 11 result={‘isAuth‘:False} 12 model= User_model.User_mod() #实例化一个对象,将查询结果逐一添加给对象的属性 13 sql ="SELECT id,username,sample_count,task_count FROM User WHERE username =‘%s‘ AND password = ‘%s‘" % (username,password) 14 rows = user_dal.User_Dal.query(sql) 15 print(‘查询结果>>>‘,rows) 16 if rows: 17 result[‘isAuth‘] = True 18 model.id = rows[0] 19 model.username = rows[1] 20 model.sample_count = rows[2] 21 model.task_count = rows[3] 22 return result,model 23 24 #flask_login回调函数执行的,需要通过用户唯一的id找到用户对象 25 @classmethod 26 def load_user_byid(cls,id): 27 print(‘load_user_byid‘) 28 sql="SELECT id,username,sample_count,task_count FROM User WHERE id=‘%s‘" %id 29 model= User_model.User_mod() #实例化一个对象,将查询结果逐一添加给对象的属性 30 rows = user_dal.User_Dal.query(sql) 31 if rows: 32 result = {‘isAuth‘: False} 33 result[‘isAuth‘] = True 34 model.id = rows[0] 35 model.username = rows[1] 36 model.sample_count = rows[2] 37 model.task_count = rows[3] 38 return model 39 40 #具体执行sql语句的函数 41 @classmethod 42 def query(cls,sql,params = None): 43 result =dal.SQLHelper.fetch_one(sql,params) 44 return result
1 from flask import Flask,render_template,redirect 2 from flask_login import LoginManager,login_user,login_required,current_user 3 from flask_wtf.form import FlaskForm 4 from wtforms import StringField, PasswordField, BooleanField 5 from wtforms.validators import Length,DataRequired,Optional 6 from User_dal import user_dal 7 8 app = Flask(__name__) 9 10 #项目中设置flask_login 11 login_manager = LoginManager() 12 login_manager.init_app(app) 13 app.config[‘SECRET_KEY‘] = ‘234rsdf34523rwsf‘ 14 15 #flask_wtf表单 16 class LoginForm(FlaskForm): 17 username = StringField(‘账户名:‘, validators=[DataRequired(), Length(1, 30)]) 18 password = PasswordField(‘密码:‘, validators=[DataRequired(), Length(1, 64)]) 19 remember_me = BooleanField(‘记住密码‘, validators=[Optional()]) 20 21 22 23 @app.route(‘/login‘,methods=[‘GET‘,‘POST‘]) 24 def login(): 25 form = LoginForm() 26 if form.validate_on_submit(): 27 username = form.username.data 28 password = form.password.data 29 result = user_dal.User_Dal.login_auth(username,password) 30 model=result[1] 31 if result[0][‘isAuth‘]: 32 login_user(model) 33 print(‘登陆成功‘) 34 print(current_user.username) #登录成功之后可以用current_user来取该用户的其他属性,这些属性都是sql语句查来并赋值给对象的。 35 return redirect(‘/t‘) 36 else: 37 print(‘登陆失败‘) 38 return render_template(‘login.html‘,formid=‘loginForm‘,action=‘/login‘,method=‘post‘,form=form) 39 return render_template(‘login.html‘,formid=‘loginForm‘,action=‘/login‘,method=‘post‘,form=form) 40 ‘‘‘登录函数,首先实例化form对象 41 然后通过form对象验证post接收到的数据格式是否正确 42 然后通过login_auth函数,用username与password向数据库查询这个用户,并将状态码以及对象返回 43 判断状态码,如果正确则将对象传入login_user中,然后就可以跳转到正确页面了‘‘‘ 44 45 46 @login_manager.user_loader 47 def load_user(id): 48 return user_dal.User_Dal.load_user_byid(id) 49 ‘‘‘ 50 load_user是一个flask_login的回调函数,在登陆之后,每访问一个带Login_required装饰的视图函数就要执行一次, 51 该函数返回一个用户对象,通过id来用sql语句查到的用户数据,然后实例化一个对象,并返回。 52 ‘‘‘ 53 54 #登陆成功跳转的视图函数 55 @app.route(‘/t‘) 56 @login_required 57 def hello_world(): 58 print(‘登录跳转‘) 59 return ‘Hello World!‘ 60 61 #随便写的另一个视图函数 62 @app.route(‘/b‘) 63 @login_required 64 def hello(): 65 print(‘视图函数b‘) 66 return ‘Hello b!‘ 67 68 69 70 if __name__ == ‘__main__‘: 71 app.run()
标签:http 图片 nal 目录结构 数据 type mod min alt
原文地址:https://www.cnblogs.com/ArmoredTitan/p/8985656.html