flask基础002
实现hello world
# 导入Flask模块 from flask import Flask # 创建app实例 app = Flask(__name__) # 通过装饰器路由,把url与视图函数绑定起来 @app.route('/') def index(): return 'hello word!' if __name__ == '__main__': # 运行当前Flask应用程序 app.run(debug=True)
Flask 程序初始化参数
- import_name
- Flask程序所在的包(模块),传
__name__就可以 - 其可以决定 Flask 在访问静态文件时查找的路径
- Flask程序所在的包(模块),传
- static_path
- 静态文件访问路径(不推荐使用,使用 static_url_path 代替)
- static_url_path
- 静态文件访问路径,可以不传,默认为:
/ + static_folder
- 静态文件访问路径,可以不传,默认为:
- static_folder
- 静态文件存储的文件夹,可以不传,默认为
static
- 静态文件存储的文件夹,可以不传,默认为
- template_folder
- 模板文件存储的文件夹,可以不传,默认为
templates
- 模板文件存储的文件夹,可以不传,默认为
Flask 程序相关配置加载方式
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, } 方式一: app.config['DEBUG'] = True PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...) 方式二: app.config.from_pyfile("python文件名称") 如: settings.py DEBUG = True app.config.from_pyfile("settings.py") app.config.from_envvar("环境变量名称") 环境变量的值为python文件名称名称,内部调用from_pyfile方法 app.config.from_json("json文件名称") JSON文件名称,必须是json格式,因为内部会执行json.loads app.config.from_mapping({'DEBUG':True}) 字典格式 app.config.from_object("python类或类的路径") app.config.from_object('pro_flask.settings.TestingConfig') settings.py 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 PS: 从sys.path中已经存在路径开始写 PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录
class Config(object): # 这里面写配置文件初始化 DEBUG= False # 这里写重写配置文件 class DevelopmentConfig(Config): DEBUG = True
from flask import Flask app = Flask(__name__) # 使用配置文件 app.config.from_object('settings.DevelopmentConfig') @app.route('/') def index(): return "hello world" if __name__ == '__main__': app.run()
配置文件的方式很多,但是最常用的是settings
app.run() 参数
app.run(host="0.0.0.0", port=5000, debug = True)
可以指定运行的主机IP地址,端口,是否开启调试模式
路由
@app.route('/user/<username>')
@app.route('/post/<int:post_id>')
@app.route('/post/<float:post_id>')
@app.route('/post/<path:path>')
@app.route('/login', methods=['GET', 'POST'])
正则匹配路由
在 web 开发中,可能会出现限制用户访问规则的场景,那么这个时候就需要用到正则匹配,根据自己的规则去限定请求参数再进行访问
具体实现步骤为:
1)导入转换器基类:在 Flask 中,所有的路由的匹配规则都是使用转换器对象进行记录
rom werkzeug.routing import BaseConverter
2)自定义转换器:自定义类继承于转换器基类
# 自定义正则转换器 class RegexConverter(BaseConverter): def __init__(self, url_map, *args): super(RegexConverter, self).__init__(url_map) # 将接受的第1个参数当作匹配规则进行保存 self.regex = args[0]
3)添加转换器到默认的转换器字典中
app = Flask(__name__) # 将自定义转换器添加到转换器字典中,并指定转换器使用时名字为: re app.url_map.converters['re'] = RegexConverter
4)使用自定义转换器实现自定义匹配规则
@app.route('/user/<re("[0-9]{3}"):user_id>') def user_info(user_id): return "user_id 为 %s" % user_id
from flask import Flask from werkzeug.routing import BaseConverter class RouteCon(BaseConverter): def __init__(self,url_map,*args): super(RouteCon,self).__init__(url_map) self.aaa = args[0] app = Flask(__name__) app.config.from_object('settings.DevelopmentConfig') app.url_map.converters['re'] = RouteCon # 定义好之后只需要修改这个地方 @app.route('/index/<re("[\d]{3}"):user_id>') def index(user_id): return "hello world %s" %user_id if __name__ == '__main__': app.run()
运行测试:http://127.0.0.1:5000/index/123 ,如果访问的url不符合规则,会提示找不到页面
自定义转换器其他两个函数实现
to_python
to_url
系统自带转换器
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
def auth(func): def inner(*args, **kwargs): print('before') result = func(*args, **kwargs) print('after') return result return inner @app.route('/index.html',methods=['GET','POST'],endpoint='index') @auth def index(): return 'Index' 或 def index(): return "Index" self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"]) or app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"]) app.view_functions['index'] = index 或 def auth(func): def inner(*args, **kwargs): print('before') result = func(*args, **kwargs) print('after') return result return inner class IndexView(views.View): methods = ['GET'] decorators = [auth, ] def dispatch_request(self): print('Index') return 'Index!' app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name=endpoint 或 class IndexView(views.MethodView): methods = ['GET'] decorators = [auth, ] def get(self): return 'Index.GET' def post(self): return 'Index.POST' app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) # name=endpoint @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"] strict_slashes=None, 对URL最后的 / 符号是否严格要求, 如: @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>') 或 def func(adapter, nid): return "/home/888" @app.route('/index/<int:nid>', redirect_to=func) subdomain=None, 子域名访问 from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'wupeiqi.com:5000' @app.route("/", subdomain="admin") def static_index(): """Flask supports static subdomains This is available at static.your-domain.tld""" return "static.your-domain.tld" @app.route("/dynamic", subdomain="<username>") def username_index(username): """Dynamic subdomains are also supported Try going to user1.your-domain.tld/dynamic""" return username + ".your-domain.tld" if __name__ == '__main__': app.run() a.注册路由原理
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) self.regex = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值 :param value: :return: """ return int(value) def to_url(self, value): """ 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 :param value: :return: """ val = super(RegexConverter, self).to_url(value) return val # 添加到flask中 app.url_map.converters['regex'] = RegexConverter @app.route('/index/<regex("\d+"):nid>') def index(nid): print(url_for('index', nid='888')) return 'Index' if __name__ == '__main__': app.run() b. 自定制正则路由匹配
1.给路由传参
使用同一个视图函数来显示不同用户的个人信息
# 路由传递参数 @app.route('/user/<user_id>') def user_info(user_id): return 'hello %s' % user_id
路由传递的参数默认当做 string 处理,也可以指定参数的类型
# 路由指定传递参数 @app.route('/user/<int:user_id>') def user_info(user_id): return 'hello %d' % user_id
ps:当在URL后面输入对应类型的时候回显示出来
2.指定请求方式
在 Flask 中,定义一个路由,默认的请求方式为:
GET\OPTIONS(自带)\HEAD(自带) 除了GET不常用
如果想添加请求方试
@app.route('/demo2', methods=['GET', 'POST']) def demo2(): # 直接从请求中取到请求方式并返回 return request.method
3.使用 PostMan 对请求进行测试
安装方式1:去 Chrome 商店直接搜索 PostMan 扩展程序进行安装
安装方式2:https://www.getpostman.com/ 官网下载桌面版安装方式3:将已下载好的 PostMan 插件文件夹拖入到浏览器
打开 Chrome 的扩展程序页面,打开 开发者模式 选项 扩展程序
from flask import Flask from flask import request app = Flask(__name__) app.config.from_object('settings.DevelopmentConfig') @app.route('/',methods=["GET","POST"]) def index(): # 获得请求的方式 print(request.method) # 获得URL?后面的值 print(request.args) # 通过key获的值 print(request.form.get('key')) # 获得json数据 print(request.json) return "hello world" if __name__ == '__main__': app.run()
浙公网安备 33010602011771号