Flask 和pythonweb框架介绍、flask快速使用、登录,显示用户信息小案例、配置文件方式、 路由系统
Flask 和pythonweb框架介绍
Flask 和pythonweb框架的区别:
Django框架:
大而全,内置的app很多,第三方的app很多
Flask框架:
小而精,没有过多的内置app,只能完成web框架的基本功能,很多功能都需要借助第三方
python异步框架:
fastapi:https://fastapi.tiangolo.com/zh/
python的异步web框架,不少公司还在用
sanic:Python的异步web框架,供支持异步高并发请求的web服务
tornado:异步框架(用的比较少)
djagno是同步框架还是异步框架,djagno 3.x以后支持异步
同步框架和异步框架的区别:
同步框架的意思:一个线程只处理一个请求
异步框架的意思:一个线程可以处理多个请求
异步框架可以很显著的提高并发量
Flask的快速使用
Flask是一个基于Python开发并依赖于jinjia2模板和Werkzeug WSGI服务的一个微型框架
jinjia2:模板语法,和Django的dtl非常像
Werkzeug WSGI:符合wsgi协议的文本服务器,Django使用的是wgsgiref
wsgi协议:web服务网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的web服务器和web应用程序之间的一种简单而通用的接口
wsgirf写web
from wsgiref.simple_server import make_server
def mya(environ,start_response):
# request就是environ包装后的对象
print(environ)
start_response('200 ok',[('Content-Type', 'text/html')])
if environ.get('PATH_INFO') == '/index':
with open('index.html','rb') as f:
data=f.read()
elif environ.get('PATH_INFO') == '/login':
with open('login.html','rb') as f:
data=f.read()
else:
data=b'<h3>hello</h3>'
return [data]
# 做成了response
if __name__ == '__main__':
myserver=make_server('',8008,mya)
# print('监听8008')
myserver.serve_forever()
使用werkzeug写web
from werkzeug.wrappers import Request,Response
@Request.application
def hello(request):
return Response('hello')
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple('localhost',400,hello)
flask快速使用
安装flask
pip install flask 安装依赖:MarkupSafe,Werkzeug,jinjia2,flask
小案例快速上手
from flask import Flask
app=Flask(__name__)
# 用装饰器来注册路由
@app.route('/index')
def index():
return 'hello index'
@app.route('/')
def home():
return 'hello home'
if __name__ == '__main__':
app.run()
使用flask编写登录小案例
1. login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<p>用户名:<input type="text" name="username"></p>
<p>密码:<input type="password" name="password"></p>
<input type="submit" value="登录">{{error}}
</form>
</body>
</html>
2.home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>用户列表</h3>
<table>
{% for k,v in user_dict.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v['name']}}</td>
<td>{{v.get('name')}}</td>
<td><a href="/detail/{{k}}">查看详情</a></td>
</tr>
{% endfor %}
</table>
</body>
</html>
3.detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>名字是:{{user.name}}</p>
<p>年龄是:{{user['age']}}</p>
<p>性别是:{{user.get('gender')}}</p>
<p>{{user.text}}</p>
</body>
</html>
4.py文件
from flask import Flask, request, render_template, session, redirect
app = Flask(__name__)
# 使用session需要秘钥
app.secret_key = 'abcdddd12'
USERS = {
1: {'name': '张三', 'age': 18, 'gender': '男', 'text': "道路千万条"},
2: {'name': '李四', 'age': 28, 'gender': '男', 'text': "安全第一条"},
3: {'name': '王五', 'age': 18, 'gender': '女', 'text': "行车不规范"},
}
@app.route('/login',methods=['GET','POST'])
def index():
# 判断方式
if request.method =='GET':
# 返回登陆页面给用户
return render_template('login.html')
# post请求判断用户名和密码
if request.method =='POST':
username=request.form.get('username')
password=request.form.get('password')
# 校验用户名和密码
if username =='zx' and password=='123':
# 校验成功,保存session
session['name']=username
# 重定向到home页面
return redirect('/')
else:
return render_template('login.html',error='用户名或者密码错误')
# 编写首页
@app.route('/')
def home():
# 先校验用户是否登录
if session.get('name'):
return render_template('home.html',user_dict=USERS)
else:
# 没有登录的话就跳转到登录
return redirect('/login')
# 编写用户详情页面
@app.route('/detail/<int:pk>')
def detail(pk):
# 先校验用户是否登录
if session.get('name'):
user_detail=USERS[pk]
return render_template('detail.html',user=user_detail)
else:
# 没有登录的话就跳转到登录
return redirect('/login')
if __name__ == '__main__':
app.run()
小知识点
1 注册路由 app.route(路径,methods=[请求方式get,post])
2 新手四件套:
-render_template 渲染模板 跟django有区别
-redirect 重定向
-return 字符串 返回字符串
-jsonify 返回json格式
3 请求的request对象,是全局的,直接导入使用即可,在不同视图函数中不会混乱
request.method 请求方式
request.form post请求的body体的内容转成了字典
4 session 全局的,直接导入使用即可,一定要指定秘钥app.secret_key = 'asdfasdfa33aef3aefads'
放值:session['name']='lqz'
取值:session.get('name')
5 模板的渲染
-兼容django的dtl
-更强大,可以加括号,字典可以.get .values() .items()
-{% for %}
6 转换器@app.route('/detail/<int:pk>')
flask配置文件
flask不同于Django可以在setting文件编写配置,flask配置文件的方式有多种,相较于Django更加灵活
方法一:直接编写
# 用于测试
app.debug = True
# 调试模式,提示信息更详细,修改代码不需要重启
app.secret_key='aabgggggg'
# 秘钥
方法二:使用app.config
# 直接使用flask实例化的对象点出config的方式添加
app.config['DEBUG']=True
app.config['SECRET_KEY']='sdfasdfasd'
print(app.config)
方法三:使用py文件,然后导入
# 将配置编写在py文件中,然后使用方法导入(不常用)
app.config.from_pyfile("settings.py") # 变量必须大写
print(app.config)
方法四:使用类导入
# 同样是创建py文件,区别是写在类中,可以上线时候可以指定使用哪套
app.config.from_object('settings.DevelopmentConfig')
app.config.from_object('settings.ProductionConfig')
print(app.config)
方法五:其他方法
# 1、通过环境变量导入
app.config.from_envvar("环境变量名称")
# 2、通过json文件载入
app.config.from_json("json文件名称")
# JSON文件名称,必须是json格式,因为内部会执行json.loads
# 3、字典格式、配置中心
app.config.from_mapping({'DEBUG': True})
常用配置字段
-DEBUG # debug模式
-SECRET_KEY # session的key值 (密钥)
-SESSION_COOKIE_NAME # 用户浏览器上cokie会变成设置的名字
-PERMANENT_SESSION_LIFETIME # session过期时间
# 内置的配置字段,其他可以写自己的,比如 redis的连接地址,mysql的连接地址
路由系统
路由本质
# 咱们这样写
@app.route('/login')
def index():
pass
#本质是---》index=app.route('/login')(index)
# app.route('/login')的执行结果 decorator 函数
-rule是路径
-其他参数都给了options
# 然后 decorator(index)--->在执行
# f是index
endpoint = options.pop("endpoint", None) # 目前没有endpoint,是None
# 核心,本质--》self就是实例化得到的app对象,flask对象
# app对象中有个方法add_url_rule,这是在添加路由
# 不使用装饰器,自己注册路由
self.add_url_rule(rule, endpoint, f, **options)
return f
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
def decorator(f: T_route) -> T_route:
endpoint = options.pop("endpoint", None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
# 可以不使用装饰器的方式,注册路由
app.add_url_rule('/', endpoint=None, view_func=home, methods=['GET'])
# flask路由的本质是app对象的add_url_rule完成路由的注册
add_url_rule参数
# rule URL规则
# view_func 视图函数名称
# defaults = None 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}为函数提供参数
# endpoint = None, 路径的别名,名称,用于反向解析URL,即: url_for('名称')
# methods = None, 允许的请求方式,如:["GET", "POST"]
#对URL最后的 / 符号是否严格要求
strict_slashes = None
'''
@app.route('/index', strict_slashes=False)
#访问http://www.xx.com/index/ 或http://www.xx.com/index均可
@app.route('/index', strict_slashes=True)
#仅访问http://www.xx.com/index
'''
#重定向到指定地址
redirect_to = None,
'''
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')
'''
# 需要记住的
# rule
# view_func
# defaults
# endpoint
# methods
转换器
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
# 了解:让路由支持正则(忽略掉)