配置文件
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目录
路由系统
@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'])
常用路由系统有以上五种,所有的路由系统都是基于以下对应关系来处理:
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
@app.route('/index', methods=['GET', 'POST'], endpoint='n1')
def index():
print(url_for('n1'))
return 'Index'
endpoint 就是 django 中的 name,通过它反向生成 URL,不写默认是函数名
路由本质
from flask import Flask
app = Flask(__name__)
app.debug = True
app.secret_key = "dsagsd"
'''
第一步
@app.route('/', methods=['GET', 'POST'], endpoint='n1')
def route(self, rule, **options): self是app对象
# rule是 /
# options 是 {methods=['GET', 'POST'], endpoint='n1'}
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator 返回给上面的app.route
第二步
相当于写了一个 @decorator, 立即执行decorator函数
即decorator(index), endpoint已经是n1
然后执行self.add_url_rule(), self是app
'''
@app.route('/', methods=['GET', 'POST'], endpoint='n1')
def index():
return 'Hello World!'
def login():
return '登录'
app.add_url_rule('/login', 'n2', login, methods=['GET', 'POST'])
if __name__ == '__main__':
app.run()
CBV
from flask import Flask, views
def auth(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
return res
return inner
app = Flask(__name__)
app.debug = True
app.secret_key = "fdafsa"
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
if __name__ == '__main__':
app.run()
add_url_rude 参数
@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:重定向到指定地址
# redirect_to:重定向到指定地址
from flask import Flask
app = Flask(__name__)
app.debug = True
app.secret_key = "dsagsd"
@app.route('/index', methods=['GET', 'POST'], endpoint='n1', redirect_to="/index2")
def index():
return '公司旧页面'
@app.route('/index2', methods=['GET', 'POST'], endpoint='n2')
def index():
return '公司新页面'
if __name__ == '__main__':
app.run()
- subdomain=None:子域名访问
# 子域名访问
from flask import Flask, views, url_for
app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'qiuxi.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()
支持正则的路由
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()
模板
Flask 使用的是 Jinja2 模板,所以其语法和 Django 无差别
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>自定义函数</h1>
{{ ww()|safe }} <!-- 与Django的区别是可以加括号,可以传参 -->
</body>
</html>
from flask import Flask, render_template, Markup
app = Flask(__name__)
def qiuxi():
# return Markup('<h1>qiuxi</h1>') # 前端页面不加safe时使用
return '<h1>qiuxi</h1>'
@app.route('/login', methods=['GET', 'POST'])
def login():
return render_template('login.html', ww=qiuxi)
if __name__ == '__main__':
app.run()