Flask框架:配置文件与路由
1、Flask配置文件
1 import os 2 import logging 3 import datetime 4 5 basedir = os.path.abspath(os.path.dirname(__file__)) 6 7 class InfoFilter(logging.Filter): 8 def filter(self, record): 9 """ 10 only use INFO 11 筛选,只需要INFO级别的log 12 :param record: 13 :return: 14 """ 15 if logging.INFO <= record.levelno <logging.ERROR: 16 # 已经是INFO级别了 17 # 然后利用父类,返回1 18 return super().filter(record) 19 else: 20 return 0 21 22 23 class BaseConfig(object): 24 DEBUG = False 25 TESTING = False 26 PROPAGATE_EXCEPTIONS = None 27 PRESERVE_CONTEXT_ON_EXCEPTION = None 28 SECRET_KEY = None 29 PERMANENT_SESSION_LIFETIME = datetime.timedelta(31) 30 USE_X_SENDFILE = False 31 LOGGER_NAME = "app" 32 LOGGER_HANDLER_POLICY = "always" 33 SERVER_NAME = None 34 APPLICATION_ROOT = None 35 SESSION_COOKIE_NAME = "session" 36 SESSION_COOKIE_DOMAIN = None 37 SESSION_COOKIE_PATH = None 38 SESSION_COOKIE_HTTPONLY = True 39 SESSION_COOKIE_SECURE = False 40 SESSION_REFRESH_EACH_REQUEST = True 41 MAX_CONTENT_LENGTH = None 42 SEND_FILE_MAX_AGE_DEFAULT = datetime.timedelta(0, 43200) 43 TRAP_BAD_REQUEST_ERRORS = False 44 TRAP_HTTP_EXCEPTIONS = False 45 EXPLAIN_TEMPLATE_LOADING = False 46 PREFERRED_URL_SCHEME = 'http' 47 JSON_AS_ASCII = True 48 JSON_SORT_KEYS = True 49 JSONIFY_PRETTYPRINT_REGULAR = True 50 JSONIFY_MIMETYPE = 'application / json' 51 TEMPLATES_AUTO_RELOAD = None 52 53 LOG_PATH = os.path.join(basedir, 'logs') 54 LOG_PATH_ERROR = os.path.join(LOG_PATH, 'error.log') 55 LOG_PATH_INFO = os.path.join(LOG_PATH, 'info.log') 56 LOG_FILE_MAX_BYTES =100*1024*1024 57 # 轮转数量是10个 58 LOG_FILE_BACKUP_COUNT = 10 59 60 @classmethod 61 def init_app(cls, app): 62 pass 63 64 class ProductionConfig(BaseConfig): 65 DEBUG = False 66 67 class DevelopmentConfig(BaseConfig): 68 69 DEBUG = True 70 SECRET_KEY = "avafaewffewfaew" 71 72 @classmethod 73 def init_app(cls, app): 74 # BaseConfig.init_app(app) 75 super().init_app(app) 76 77 import logging 78 from logging.handlers import RotatingFileHandler 79 # Formatter 80 formatter = logging.Formatter( 81 '%(asctime)s %(levelname)s %(process)d %(thread)d ' 82 '%(pathname)s %(lineno)s %(message)s') 83 84 # FileHandler Info 85 file_hander_info = RotatingFileHandler(filename=cls.LOG_PATH_INFO) 86 file_hander_info.setFormatter(formatter) 87 file_hander_info.setLevel(logging.INFO) 88 info_filter = InfoFilter() 89 file_hander_info.addFilter(info_filter) 90 app.logger.addHandler(file_hander_info) 91 92 # FileHandler Error 93 file_hander_error = RotatingFileHandler(filename=cls.LOG_PATH_ERROR) 94 file_hander_error.setFormatter(formatter) 95 file_hander_error.setLevel(logging.ERROR) 96 app.logger.addHandler(file_hander_error) 97 98 99 100 class TestConfig(BaseConfig): 101 102 DEBUG = True 103 104 config = { 105 'development': DevelopmentConfig, 106 'xxx': ProductionConfig, 107 'testing': TestConfig, 108 'default': DevelopmentConfig, 109 }
1 from flask import Flask,Response 2 3 app = Flask(__name__) 4 app.config.from_object("settings.DevelopmentConfig") 5 6 @app.route("/index/") 7 def index(): 8 return Response("hello") 9 10 if __name__ == "__main__": 11 app.run()
2、Flask的路由系统
2.1、路由设置的两种方式
使用装饰器@app.route:
@app.route('/xxx') def index(): return "index"
使用app.add_url_rule添加:
def index(): return "index" app.add_url_rule("/xxx",None,index)
注意事项:
- 不用让endpoint重名
- 如果重名函数也一定要相同。
2.2、设置路由时的参数
rule, URL规则 view_func, 视图函数名称 endpoint=None, 名称,用于反向生成URL,即: url_for('名称') methods=None, 允许的请求方式,如:["GET","POST"] strict_slashes=None, 对URL最后的 / 符号是否严格要求, redirect_to=None, 重定向到指定地址 defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数 subdomain=None, 子域名访问
2.3、动态路由
@app.route('/index/<int:nid>',methods=['GET','POST']) def index(nid): print(nid) return "Index"
2.4、反向生成URL
endpoint:反向生成URL,默认是函数名
url_for('endpoint') 或 url_for("index", nid=10)
2.5、自定义正则
from flask import Flask,url_for app = Flask(__name__) # 步骤一:定制类 from werkzeug.routing import BaseConverter 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 # 步骤二:添加到转换器 app.url_map.converters['reg'] = RegexConverter """ 1. 用户发送请求 2. flask内部进行正则匹配 3. 调用to_python(正则匹配的结果)方法 4. to_python方法的返回值会交给视图函数的参数 """ # 步骤三:使用自定义正则 @app.route('/index/<reg("\d+"):nid>') def index(nid): print(nid,type(nid)) print(url_for('index',nid=987)) return "index" if __name__ == '__main__': app.run()
2.6、子域名
from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'wupeiqi.com:5000' """ 127.0.0.1 wupeiqi.com 127.0.0.1 web.wupeiqi.com 127.0.0.1 admin.wupeiqi.com """ # http://admin.wupeiqi.com:5000/ @app.route("/", subdomain="admin") def admin_index(): return "admin.your-domain.tld" # http://web.wupeiqi.com:5000/ @app.route("/", subdomain="web") def web_index(): return "web.your-domain.tld" # http://sdsdf.wupeiqi.com:5000/ # http://sdfsdf.wupeiqi.com:5000/ # http://asdf.wupeiqi.com:5000/ @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()