一、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']=TruePS:由于Config对象本质上是字典,所以还可以使用app.config.update(...)

方式二:

#通过py文件配置app.config.from_pyfile("python文件名称")如:settings.pyDEBUG=Trueapp.config.from_pyfile("settings.py")#通过环境变量配置app.config.from_envvar("环境变量名称")#app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])环境变量的值为python文件名称名称,内部调用from_pyfile方法app.config.from_json("json文件名称")JSON文件名称,必须是json格式,因为内部会执行json.loadsapp.config.from_mapping({'DEBUG':True})字典格式app.config.from_object("python类或类的路径")app.config.from_object('pro_flask.settings.TestingConfig')settings.pyclassConfig(object):DEBUG=FalseTESTING=FalseDATABASE_URI='sqlite://:memory:'classProductionConfig(Config):DATABASE_URI='mysql://user@localhost/foo'classDevelopmentConfig(Config):DEBUG=TrueclassTestingConfig(Config):TESTING=TruePS:从sys.path中已经存在路径开始写PS:settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录(Flask对象init方法的参数)

二、路由系统

经典写法:

@app.route('/detail/<int:nid>',methods=['GET'],endpoint='detail')

默认转换器:

DEFAULT_CONVERTERS={'default':UnicodeConverter,'string':UnicodeConverter,'any':AnyConverter,'path':PathConverter,'int':IntegerConverter,'float':FloatConverter,'uuid':UUIDConverter,}

路由系统本质

"""1.decorator=app.route('/',methods=['GET','POST'],endpoint='n1')defroute(self,rule,**options):#app对象#rule=/#options={methods=['GET','POST'],endpoint='n1'}defdecorator(f):endpoint=options.pop('endpoint',None)self.add_url_rule(rule,endpoint,f,**options)returnfreturndecorator2.@decoratordecorator(index)"""#同理deflogin():return'登录'app.add_url_rule('/login','n2',login,methods=['GET',"POST"])#与django路由类似#django与flask路由:flask路由基于装饰器,本质是基于:add_url_rule#add_url_rule源码中,endpoint如果为空,endpoint=_endpoint_from_view_func(view_func),最终取view_func.__name__(函数名)CBV(源码分析)

defauth(func):definner(*args,**kwargs):print('before')result=func(*args,**kwargs)print('after')returnresultreturninnerclassIndexView(views.View):methods=['GET']decorators=[auth,]defdispatch_request(self):print('Index')return'Index!'app.add_url_rule('/index',view_func=IndexView.as_view(name='index'))#name=endpoint#或者,通常用此方式classIndexView(views.MethodView):methods=['GET']decorators=[auth,]defget(self):return'Index.GET'defpost(self):return'Index.POST'app.add_url_rule('/index',view_func=IndexView.as_view(name='index'))#name=endpoint

app.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最后的/符号是否严格要求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>')'''#子域名访问subdomain=None,'''#C:\Windows\System32\drivers\etc\hosts127.0.0.1www.liuqingzheng.com127.0.0.1admin.liuqingzheng.com127.0.0.1buy.liuqingzheng.comfromflaskimportFlask,views,url_forapp=Flask(import_name=__name__)app.config['SERVER_NAME']='liuqingzheng.com:5000'@app.route("/",subdomain="admin")defstatic_index():"""FlasksupportsstaticsubdomainsThisisavailableatstatic.your-domain.tld"""return"static.your-domain.tld"#可以传入任意的字符串,如传入的字符串为aa,显示为aa.liuqingzheng.com@app.route("/dynamic",subdomain="<username>")defusername_index(username):"""DynamicsubdomainsarealsosupportedTrygoingtouser1.your-domain.tld/dynamic"""returnusername+".your-domain.tld"if__name__=='__main__':app.run()访问:http://www.liuqingzheng.com:5000/dynamichttp://admin.liuqingzheng.com:5000/dynamichttp://buy.liuqingzheng.com:5000/dynamic'''

支持正则

#1写类,继承BaseConverter#2注册:app.url_map.converters['regex']=RegexConverter#3使用:@app.route('/index/<regex("\d+"):nid>')正则表达式会当作第二个参数传递到类中fromflaskimportFlask,views,url_forfromwerkzeug.routingimportBaseConverterapp=Flask(import_name=__name__)classRegexConverter(BaseConverter):"""自定义URL匹配正则表达式"""def__init__(self,map,regex):super(RegexConverter,self).__init__(map)self.regex=regexdefto_python(self,value):"""路由匹配时,匹配成功后传递给视图函数中参数的值"""returnint(value)defto_url(self,value):"""使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数"""val=super(RegexConverter,self).to_url(value)returnval#添加到flask中app.url_map.converters['regex']=RegexConverter@app.route('/index/<regex("\d+"):nid>')defindex(nid):print(url_for('index',nid='888'))return'Index'if__name__=='__main__':app.run()

三、模板

比django中多可以加括号,执行函数,传参数

-支持函数加括号执行,支持传参
-flask处理了xss***,如果想显示原生html
-safe:模板中
-Markup:后台处理

fromflaskimportFlask,render_template,Markup,jsonify,make_responseapp=Flask(__name__)deffunc1(arg):returnMarkup("<inputtype='text'value='%s'/>"%(arg,))@app.route('/')defindex():returnrender_template('index.html',ff=func1)if__name__=='__main__':app.run()

index.html

<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>Title</title></head><body>{{ff('六五')}}{{ff('六五')|safe}}</body></html>

注意:

1.Markup等价django的mark_safe ,

2.extends,include一模一样

四、请求响应

fromflaskimportFlaskfromflaskimportrequestfromflaskimportrender_templatefromflaskimportredirectfromflaskimportmake_responseapp=Flask(__name__)@app.route('/login.html',methods=['GET',"POST"])deflogin():#请求相关信息#request.method#request.args#request.form#request.values#request.cookies#request.headers#request.path#request.full_path#request.script_root#request.url#request.base_url#request.url_root#request.host_url#request.host#request.files#obj=request.files['the_file_name']#obj.save('/var/www/uploads/'+secure_filename(f.filename))#响应相关信息#return"字符串"#returnrender_template('html模板路径',**{})#returnredirect('/index.html')#returnjsonify({'k1':'v1'})#response=make_response(render_template('index.html'))#response是flask.wrappers.Response类型#response.delete_cookie('key')#response.set_cookie('key','value')#response.headers['X-Something']='Avalue'#returnresponsereturn"内容"if__name__=='__main__':app.run()

五、session

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。 (app.session_interface对象)

设置:session['username']='xxx'删除:session.pop('username',None)delession['user']取值:session['user']

六、闪现

-设置:flash('aaa')-取值:get_flashed_message()-假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息-分类存flash('你的名字不是lqz是%s',category='aa')-分类取get_flashed_messages(category_filter=['aa',])

示例:

fromflaskimportFlask,flash,get_flashed_messages,request,redirectapp=Flask(__name__)app.secret_key='asdfasdf'@app.route('/index')defindex():#从某个地方获取设置过的所有值,并清除。val=request.args.get('v')ifval=='oldboy':return'HelloWorld!'flash('超时错误',category="x1")return"ssdsdsdfsd"#returnredirect('/error')@app.route('/error')deferror():"""展示错误信息:return:"""data=get_flashed_messages(category_filter=['x1'])ifdata:msg=data[0]else:msg="..."return"错误信息:%s"%(msg,)if__name__=='__main__':app.run()

message_test.py

fromflaskimportFlask,render_template,render_template_string,Markup,request,session,redirect,flash,\get_flashed_messagesapp=Flask(__name__)app.secret_key='s'app.config["DEBUG"]=True@app.route('/index')defindex():name=request.args.get('name')ifname=='lqz':return'ok'else:flash('名字错误',category='a')flash('ddddadf',category='bb')return'写入错误'#returnredirect('/order')@app.route('/order')deforder():message=get_flashed_messages(category_filter=['a'])print(message)return'order---%s'%message[0]if__name__=='__main__':app.run()

七、请求资源

1 before_request

类比django中间件中的process_request,在请求收到之前绑定一个函数做一些事情

fromflaskimportFlask,render_template,render_template_string,Markup,request,session,redirect,flash,\get_flashed_messagesapp=Flask(__name__)app.secret_key='s'app.config["DEBUG"]=True@app.route('/index')defindex():print("index")return'写入错误'@app.route('/order')deforder():print('order')return'order'@app.before_requestdefprocess_request():print('before_request')if__name__=='__main__':app.run()-----------------------------------------访问:http://127.0.0.1:5000/index页面返回:写入错误pycharm返回:127.0.0.1--[20/Feb/201919:22:11]"GET/indexHTTP/1.1"200-before_requestindex--------------------------------------------------------------------------返回:http://127.0.0.1:5000/order页面返回:orderpycharm返回:before_request127.0.0.1--[20/Feb/201919:23:50]"GET/orderHTTP/1.1"200-order2 after_request

类比django中间件中的process_response,每一个请求之后绑定一个函数,如果请求没有异常

fromflaskimportFlask,render_template,render_template_string,Markup,request,session,redirect,flash,\get_flashed_messagesapp=Flask(__name__)app.secret_key='s'app.config["DEBUG"]=True@app.route('/order')deforder():print('order')return'order'@app.after_requestdefprocess_response(response):print(response)print('response')returnresponseif__name__=='__main__':app.run()----------------------------------------------------------------访问:http://127.0.0.1:5000/order页面返回:orderpycharm返回:127.0.0.1--[20/Feb/201919:32:01]"GET/orderHTTP/1.1"200-order<Response5bytes[200OK]>response3 before_first_request

第一次请求时,跟浏览器无关

fromflaskimportFlask,render_template,render_template_string,Markup,request,session,redirect,flash,\get_flashed_messagesapp=Flask(__name__)app.secret_key='s'app.config["DEBUG"]=True@app.route('/order')deforder():print('order')return'order'@app.after_requestdefprocess_response(response):print(response)print('response')returnresponse@app.before_first_requestdeffirst():print('第一次访问记录')if__name__=='__main__':app.run()-------------------------------------------连续两次访问:http://127.0.0.1:5000/orderpycharm:第一次访问记录127.0.0.1--[20/Feb/201919:40:08]"GET/orderHTTP/1.1"200-order<Response5bytes[200OK]>responseorder<Response5bytes[200OK]>response127.0.0.1--[20/Feb/201919:40:26]"GET/orderHTTP/1.1"200-