falsk使用
falsk使用
一、配置文件使用debug
flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为:
{
'DEBUG': get_debug_flag(default=False), 是否开启Debug模式
'TESTING': False, 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
'USE_X_SENDFILE': False,
'LOGGER_NAME': None,
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None,
'APPLICATION_ROOT': None,
'SESSION_COOKIE_NAME': 'session',
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
'TRAP_BAD_REQUEST_ERRORS': False,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}
配置文件使用debug
"""
@author RansySun
@create 2019-12-13-18:06
"""
from flask import Flask
app = Flask(__name__)
# 方式一
# app.debug = True
# 方式二,以字典的形式
# app.config['DEBUG'] = True
# 方式三: 以文件的方式,方法比较常用
app.config.from_pyfile('settings.py')
# 方式四: 以类的形式
app.config.from_object('settings.SettingsDebug')
@app.route('/')
def index():
return 'nDio'
if __name__ == '__main__':
app.run()
"""
总结以上方式都会实现debug调试只要通过ctrl+s都会自动刷新程序
"""
二、三板斧使用
# flask模块
from flask import Flask
# 模板渲染
from flask import render_template
# 重定向
from flask import redirect
# json字符串
from flask import jsonify
from flask import request
"""
1. 返回字符串
2.返回模板(html): reder_template
3. 跳转: redirect
4. json返回
"""
app = Flask(__name__)
@app.route('/')
def index():
return 'ko'
# 页面html渲染
@app.route('/index')
def index1():
"""
会自动到templates中查找对应的html,
templates文件夹名称是可以更改的,换成其他的名字在配置文件中都可以修改
:return:
"""
return render_template("index.html")
@app.route('/home')
def route_redirect():
"""
重定向跳转页面(另一个路由页面)
:return:
"""
return redirect('/index')
@app.route('/json')
def route_json():
"""
返回json字符串
:return:
"""
data_dic = {'name':'json', 'age': 18}
return jsonify(data_dic)
if __name__ == '__main__':
app.run()
三、第二种路由跳转方式(路由本质)
from flask import Flask
app = Flask(__name__)
def index():
return 'ok'
# 指定路由跳转,第二参数为指定路由处理的函数地址
app.add_url_rule('/index', view_func=index)
if __name__ == '__main__':
app.run()
四、cbv实现
4.1cbv请求实现
from flask import Flask
app = Flask(__name__)
# 简单模式
from flask import views
class IndexView(views.View):
# 允许访问的请求方式
methods = ['GET', 'post']
# 给dispatch_request加装饰器
# decorators = [login,]
# 继承了views.View必须实现这方法
# 当请求来了之后首先进入这个方法
"""
不管什么请求都会进入这个函数
def dispatch_request(self):
print('index')
return 'cbv!'
"""
def dispatch_request(self):
print('index')
# return 'cbv!'
# 实现对应的请求方式
return self.get()
def post(self):
print("post")
return 'index post'
def get(self):
print("get")
return 'dispatch_request 实现get方式转发'
# 在cbv中name必须要传,用于反射,name=endpoint,view.__name__= index_name
app.add_url_rule('/', view_func=IndexView.as_view(name='index_name'))
if __name__ == '__main__':
app.run()
总结:
- cbv实现需要继承views.View来实现,并且需要重现dispatch_request方法,实现请求响应,所有请求方式都会进入dispatch_request方法中,如此来就可以实现对应的请求响应;
- methods属性来设置允许响应的请求方式
- dispatch_request实现对应的请求响应,get,post等请求方式
- 导入
from flask.globals import request
可以获取请求方式,请求方式只有在methods设置才可以获取,通过看源码可以了解到,request.method.lower()
4.2cbv向对应请求方式进行响应,get,post
# 另外一种方式,根据请求方式作出对应的请求响应
class IndexMethod(views.MethodView):
# 实现请求的方式,只有写了之后对应请求方式才会被访问到,
methods = ['GET', 'post']
def get(self):
return 'index GET请求'
def post(self):
return 'index POST请求'
# app.add_url_rule('/index', view_func=IndexMethod.as_view(name='index'))
if __name__ == '__main__':
app.run()
总结:
-
如果想要对对应的请求作出对应的响应就需要继承views.MethodView来实现
-
methods:属性来实现允许请求的方式
-
可以实现的实质是views.MethodView实现了dispatch_request方法重写,什么请求方式来就响应对应的请求方式,源码分析如下:
def dispatch_request(self, *args, **kwargs): # 获取请求的方式 meth = getattr(self, request.method.lower(), None) # If the request method is HEAD and we don't have a handler for it # retry with GET. # 如果请求方式为None那么设置他为get请求方式 if meth is None and request.method == "HEAD": meth = getattr(self, "get", None) # 如果还未空则抛出异常 assert meth is not None, "Unimplemented method %r" % request.method # 执行对应的请求享用 return meth(*args, **kwargs)
五、路由参数配置说明
from flask import Flask, url_for app = Flask(__name__) # 真实请求的url 反射url 请求的方法 设置为True路由必须自己手动加斜杆 根据实际请求地址重定向到index2中,浏览器路由会自动改变 @app.route('/index/', endpoint='url_for', methods=['GET', 'post'], strict_slashes=True, redirect_to='/index2') def index(): # 反射机制 # 实现反向解析,获取真实url路径 print(url_for('url_for')) return '路由参数route实现' @app.route("/index2") def index2(): return "吃饭去了" if __name__ == '__main__': app.run()
总结:
- endpoint='url_for',url_for可以随意指定实现路由反射机制需要导入url_for模块一起使用
- methods: 指明请求响应的方式
- strict_slashes: 因为浏览器请求会自动在路由后面添加斜杠,如果strict_slashes设置为True怎会在后台路由请求的时候需要手动在路由中添加一个头斜杠/来标识请求,如果为false则不需要手动设置
- redirect_to:实现路由页面的重定向,重定向后浏览器上面的路由会发生变化
六、路由过滤类型
主要有这几种类型过滤:
string
: 默认的数据类型,接收没有任何斜杠" /"的字符串int
: 整型float
: 浮点型path
: 和string类型相似,但是接受斜杠,如:可以接受参数/aa/bb/cc/多条放在一起uuid
: 只接受uuid格式的字符串字符串,提示:uuid为全宇宙唯一的串
from flask import Flask app = Flask(__name__) # 指定路由参数的类型 @app.route("/<int:flag>") def index(flag): print(type(flag)) return f"设置路由参数的类型 {flag}" if __name__ == '__main__': app.run()
总结:
- 设置路由的的数据类型,值得注意的是在使用类型的时候,要保证请求数据类型的统一,否则将会请求失败,数据请求不到
七、自定义路由转化器参数
# 1 写类,继承BaseConverter
# 2 注册:app.url_map.converters['regex'] = RegexConverter
# 3 使用:@app.route('/index/<regex("\d+"):nid>') 正则表达式会当作第二个参数传递到类中
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter
app = Flask(import_name=__name__)
class RegexConverter(BaseConverter):
"""":
自定义URL匹配规则的正则表达式
"""
def __init__(self, map, regex):
super(RegexConverter, self).__init__(map)
def to_python(self, value):
"""
路由匹配是,匹配成功后传递给视图函数中参数的值
:param value:
:return:
"""
# 会自动将数据拼接在后面没有斜线
return int(value) + 123
def to_url(self, value):
"""
使用url_for反向生成url时, 传递的参数经过该方法处理,返回的值用于生成URL中的参数
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
# 进行反省解析的时候拼接的参数会有 斜杆 / 拼接在后面 /index/888json
return val + "json"
# 将匹配规则添加到flask中
app.url_map.converters['regex'] = RegexConverter
@app.route("/index/<regex('\d+'):id>")
def index(id):
print(id)
print(url_for("index", id='888'))
return '自定义路由转化器'
if __name__ == '__main__':
app.run()
总结:
- 写类,继承BaseConverter
- 注册:app.url_map.converters['regex'] = RegexConverter
- 使用:@app.route('/index/<regex("\d+"):nid>') 正则表达式会当作第二个参数传递到类中,其中regex名字与注册的名字相同
- 在路由请求过来的时候首先进入自己自定义的类中的to_python中实现对数据的处理,将处理之后的请求路由在返回给实际的函数中的的参数,作为函数的参数返回
八、模板语法
1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
</head>
<body>
模板渲染1
<h1>用户列表</h1>
<table>
{{ data }}
{% for k,v in data.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v['name']}}</td>
<td>{{v.get('name')}}</td>
</tr>
{% endfor %}
</table>
<br>
{{ flag }}
{% if flag %}
{{name}}
{% else %}
{{name1}}
{% endif %}
<br>
<!--解析html -->
{{ html2|safe}}
<!-- 函数可以自定义传参,可以加括号运行,通过Markup()来实现解析html -->
{{ func("后台函数, 模板解析")}}
</body>
</html>
2.python
from flask import Flask, render_template, Markup
app = Flask(__name__)
USERS = {
1: {'name': '张三', 'age': 18, 'gender': '男', 'text': "道路千万条"},
2: {'name': '李四', 'age': 28, 'gender': '男', 'text': "安全第一条"},
3: {'name': '王五', 'age': 18, 'gender': '女', 'text': "行车不规范"},
}
# 自定义函数,在前端html中使用
def func(args):
return Markup(f'<h1> 后台Markup模板渲染 </h1>{args}')
@app.route("/index")
def index():
data = USERS
flag = True
html = '<h1>模板渲染解析</h1>'
# data参数将数据传递给前端页面,向页面传递的参数名字可以随意定义,在前端使用必须以你自定义的参数为准
return render_template('template_index.html', data=data, flag=True, name='json', name2='自己定义', html2=html,func = func)
if __name__ == '__main__':
app.run()
九、session实现
"""
@author RansySun
@create 2019-12-14-19:31
"""
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'sdfjoewifndg'
# 查看session原理
# app.session_interface
# 修改session在浏览器显示的名字
app.config['SESSION_COOKIE_NAME'] = 'randy_session'
@app.route("/")
def index():
# 设置session的值
session['name'] = 'randy'
return '设置session ok'
@app.route("/index")
def index1():
# 获取session的值
print(session['name'])
return f"获取设置session的值: {session['name']}"
if __name__ == '__main__':
app.run()
if __name__ == '__main__':
app.run()
在当下的阶段,必将由程序员来主导,甚至比以往更甚。