Flask入门之一
这篇博客介绍了flask的基本配置,使用,会以我自己贫瘠的理解,拿来和django做对比
快速开始
首先需要安装flask,如果没有安装过,pycharm创建新flask项目的时候也会自动帮你装
创建完新flask项目,发现得到两个空文件夹可以一个py文件,这个文件就是flask,一个文件就可以跑起来一个服务,跟django需要这么大一个框架才能运行相比,相当的迷你了
from flask import Flask,request
app=Flask(__name__)
# 固定写法
@app.route('/') # 表示根路径
def index():
# 当前请求地址,当前请求携带过来的数据
print(request.path)
return 'hello world'
@app.route('/hello') # 表示/hello路径
def hello():
print(request.path)
return 'hello hellohello'
if __name__ == '__main__':
app.run()
# run里面有一些参数可以配置端口和ip,默认不填的话就是本机127.0.0.1
在上面例子里,可以发现和django的不同。所有的django请求都会有一个入参:request,从而获取当次请求的数据,请求头,请求头一类的。而flask中在请求下面的函数里不需要传入request,就可以在不同的位置拿到不同的请求。
lowB三板斧
在django中我们有redirect,httpresponse,render,在flask中当然有类似的功能
以一个例子来看如何使用flask中的三板斧,还有一些其他用法
main.py
from flask import Flask,render_template,request,redirect,session,url_for
app = Flask(__name__)
app.debug = True
app.secret_key = 'sdfsdfsdfsdf'
USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
@app.route('/detail/<int:nid>',methods=['GET'])
# 在url中接收一个int,赋值给nid,在函数内可以用得上
def detail(nid):
user = session.get('user_info')
# 相当于django里的request.session
if not user:
return redirect('/login')
info = USERS.get(nid)
return render_template('detail.html',info=info)
# 相当于django中的render,返回一个html页面。可以在后面给这个页面带一些值
@app.route('/index',methods=['GET'])
def index():
user = session.get('user_info')
if not user:
# return redirect('/login')
url = url_for('l1')
# 重定向的可以是路径,也可以是别名
return redirect(url)
return render_template('index.html',user_dict=USERS)
@app.route('/login',methods=['GET','POST'],endpoint='l1')
def login():
if request.method == "GET":
return render_template('login.html')
else:
# request.query_string
user = request.form.get('user')
pwd = request.form.get('pwd')
if user == 'cxw' and pwd == '123':
session['user_info'] = user
return redirect('http://www.baidu.com')
return render_template('login.html',error='用户名或密码错误')
if __name__ == '__main__':
app.run()
detail.html
Copy<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>详细信息 {{info.name}}</h1>
<div>
{{info.text}}
</div>
</body>
</html>
index.html
Copy<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户列表</h1>
<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>
login.html
Copy<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form method="post">
<input type="text" name="user">
<input type="text" name="pwd">
<input type="submit" value="登录">{{error}}
</form>
</body>
</html>
总结
1 三板斧:
-return 字符串
-return render_template('index.html')
-return redirect('/login')
2 路由写法(路径,支持的请求方式,别名)
@app.route('/login',methods=['GET','POST'],endpoint='l1')
如果不写别名,会把函数名作为别名,别名不允许重复
如果有其他装饰器,注意装饰器的执行顺序,由上往下执行
3 模板语言渲染
-同dtl,但是比dtl强大,支持加括号执行,字典支持中括号取值和get取值
4 分组(django中的有名分组)
@app.route('/detail/<int:nid>',methods=['GET'])
def detail(nid):
5 反向解析
-url_for('别名')
6 获取前端传递过来的数据
# get 请求
request.query_string
# post请求
user = request.form.get('user')
pwd = request.form.get('pwd')
配置文件
像django的settings一样,flask也有一对配置文件,可以直接在view里面通过app改,不过更推荐的是分离到另一个专门的配置文件中改
app的配置文件全在app.config字典中,常用的配置DEBUG一类会往上提一层,直接修改即可
通过py文件配置
# view.py
app.config.from_pyfile("python文件名称")
# settings.py
DEBUG = True
from_object
# views.py
app.config.from_object('settings.TestingConfig')
# 类似切换dev和pro一样,不同的类中可以做不同的配置,切换的时候在这里换即可
# settings.py
# 全部继承一个基类Config,再此基础上扩展
class Config(object):
DEBUG = False
TESTING = False
DATABASE_URI = 'sqlite://:memory:'
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
路由系统
基本使用:使用装饰器
@app.route('/detail/<int:nid>',methods=['GET'],endpoint='detail')
转换器,django2以后也有这个东西,常用的就是数字浮点字符串
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
装饰器实际上调用的函数是
app.add_url_rule(路径,别名,视图函数,**)
add_url_rule参数
@app.route和app.add_url_rule参数:
rule, URL规则
view_func, 视图函数名称
defaults = None, 默认值, 当URL中无参数,函数需要参数时,使用defaults = {'k': 'v'}
为函数提供参数
endpoint = None, 名称,用于反向生成URL,即: url_for('名称')
methods = None, 允许的请求方式,如:["GET", "POST"]
#对URL最后的 / 符号是否严格要求,默认严格,False,就是不严格
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>')
'''
CBV
from flask import Flask,request,render_template,redirect
from flask import views
app=Flask(__name__)
# class IndexView(views.View):
# methods = ['GET']
# # decorators = [auth, ]
# def dispatch_request(self):
# print('Index')
# return 'Index!'
def auth(func):
def inner(*args, **kwargs):
print('before')
result = func(*args, **kwargs)
print('after')
return result
return inner
class IndexView(views.MethodView):
methods = ['GET'] # 指定运行的请求方法
# 使用装饰器
decorators = [auth, ] #加多个就是原本用语法糖从上往下的效果
def get(self):
print('xxxxx')
return "我是get请求"
def post(self):
return '我是post请求'
# 路由注册
# IndexView.as_view('index'),必须传name
app.add_url_rule('/index',view_func=IndexView.as_view('index'))
if __name__ == '__main__':
app.run()
# 用的比较少
# 继承views.MethodView,只需要写get,post,delete方法
# 如果加装饰器decorators = [auth, ]
# 允许的请求方法methods = ['GET']