一、Flask安装介绍
1 Flask是一个基于Python开发并且依赖jinja2模板(Django模板语言)和Werkug WSGI(djagno:wsgiref)服务的一个微型框架
2 对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask
框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的
处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器
3 微(micro)可以用单文件,也可以搞成django很多目录(自由定制)缓存,认证,forms,orm等都没有---》很多第三方集成进去,想用就用
不想用就不集成---》可以任意组合
二、flask的简单使用
# 1 flask的简单使用 # from flask import Flask # # 实例化得到一个flask对象 # app=Flask(__name__) # # # # flask的路由是基于装饰器 # @app.route('/') # def index(): # # 没有请求对象,没有响应对应 # return 'hello world flask' # if __name__ == '__main__': # app.run(port=8000) #2 新手四件套 # from flask import Flask,render_template,redirect,jsonify # # 实例化得到一个flask对象 # app=Flask(__name__,template_folder='templates') # # # flask的路由是基于装饰器 # @app.route('/') # def index(): # # 1返回字符串 # # return 'hello world flask' # # 2返回模板 # # return render_template('index.html') # # 3 返回重定向 # # return redirect('http://www.baidu.com') # # 4 返回json格式 # # return jsonify({'name':'lqz','age':18}) # # # if __name__ == '__main__': # app.run(port=8000) # 请求对象 from flask import Request from flask import Flask,render_template,redirect,jsonify,request # 实例化得到一个flask对象 app=Flask(__name__,template_folder='templates') # flask的路由是基于装饰器 # request对象是个全局对象,request.args--->不同请求取出来是不同请求携带的数据 # 通过不同协程/线程来区分是哪个request @app.route('/') def index(): print(request) print(request.method) # method print(request.cookies) # cookie print(request.environ) # meta print(request.form) # POST print(request.query_string) # BODY print(request.args) # GET return jsonify({'name':'lqz','age':18}) @app.route('/home/') def home(): print(request.method) print(request.args) return '我是home' if __name__ == '__main__': app.run(port=8000)
2 登录小案例
main.py
Copyfrom flask import Flask,render_template,request,redirect,session,url_for app = Flask(__name__) app.debug = True app.secret_key = 'sdfsdfsdfsdf' USERS = { 1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"}, 2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"}, 3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"}, } @app.route('/detail/<int:nid>',methods=['GET']) def detail(nid): user = session.get('user_info') if not user: return redirect('/login') info = USERS.get(nid) return render_template('detail.html',info=info) @app.route('/index',methods=['GET']) def index(): user = session.get('user_info') if not user: # return redirect('/login') url = url_for('l1') return redirect(url) return render_template('index.html',user_dict=USERS) @app.route('/login',methods=['GET','POST'],endpoint='l1') def login(): if request.method == "GET": return render_template('login.html') else: # request.query_string user = request.form.get('user') pwd = request.form.get('pwd') if user == 'cxw' and pwd == '123': session['user_info'] = user return redirect('http://www.baidu.com') return render_template('login.html',error='用户名或密码错误') if __name__ == '__main__': app.run()
detail.html
Copy<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>详细信息 {{info.name}}</h1> <div> {{info.text}} </div> </body> </html>
index.html
Copy<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>用户列表</h1> <table> {% for k,v in user_dict.items() %} <tr> <td>{{k}}</td> <td>{{v.name}}</td> <td>{{v['name']}}</td> <td>{{v.get('name')}}</td> <td><a href="/detail/{{k}}">查看详细</a></td> </tr> {% endfor %} </table> </body> </html>
login.html
Copy<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>用户登录</h1> <form method="post"> <input type="text" name="user"> <input type="text" name="pwd"> <input type="submit" value="登录">{{error}} </form> </body> </html>
三、配置文件
# flask的配置文件 from flask import Flask,request,render_template,session,redirect,url_for app=Flask(__name__) ## 方式一,直接给app设置(仅仅支持以下两个) # app.secret_key='asdfasdfasdf4545322wefaaeaesfsad' # app.debug=True # 调试模式 # 方式二,给app的config设置,可以设置所有配置文件 # 所有配置文件都是这个属性 # print(app.config) # app.config['DEBUG']=True # 第三种方式通过py文件(跟django一样了,但是不好,不常用) # app.config.from_pyfile("settings.py") # #通过环境变量配置 # import os # os.environ['DEBUG']='ddd' # app.config.from_envvar(os.environ['DEBUG']) #app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) # 环境变量的值为python文件名称名称,内部调用from_pyfile方法 # app.config.from_json("setting.json") # JSON文件名称,必须是json格式,因为内部会执行json.loads # app.config.from_mapping({'DEBUG': True}) # 通过类配置(用的多 在settings.py中写好配置类,一般有开发环境、测试环境、上线环境的配置类) # app.config.from_object('settings.DevelopmentConfig') app.config.from_object('settings.ProductionConfig') print(app.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.route('/index') def index(): return 'hello world' if __name__ == '__main__': app.run()
四、路由系统
from flask import Flask,render_template,redirect,jsonify,request
app=Flask(__name__,template_folder='templates')
# @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,
}
'''
#路由系统本质(重点)
# @app.route('/')----本质原理----》index=app.route('/')(index)
# app.route()--->decorator内存地址----》index=decorator(index)
# 不用装饰器,自己注册路由
# app.add_url_rule('/',endpoint='index',view_func=index)
# # url('/index',view.test,name='xxx')
# app.add_url_rule('/home',endpoint='home',view_func=home)
#与django路由类似
#django与flask路由:flask路由基于装饰器,本质是基于:add_url_rule
#add_url_rule 源码中,endpoint如果为空,endpoint = _endpoint_from_view_func(view_func),最终取view_func.__name__(函数名)
# endpoint如果不传,默认用函数名作为反向解析的名字,但是一定要注意多装饰器的问题
#### CBV(源码分析)
from flask.views import View,MethodView
# 如果继承的是View,必须重写dispatch_request,自己去做分发
# class Index(View):# 一般不集成view
# # 重写dispatch_request
# def dispatch_request(self):
# return '所有请求都走我,我自己分发'
# 继承MethodView----》它等同于django中的View
# class Index(MethodView):
# def get(self):
# print(request.method)
# return 'index 的get请求就过来了'
# def post(self):
# return 'post请求'
@app.route('/',defaults={'name':'lqz'},redirect_to='http://www.baidu.com')
def index(name):
return 'sss'
### add_rul_url的参数
'''
@app.route和app.add_url_rule参数:
rule, URL规则,不支持正则 (django2.0以后不用正则了)
view_func, 视图函数名称 (cbv 类名.as_view(name))
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\hosts
127.0.0.1 www.liuqingzheng.com
127.0.0.1 admin.liuqingzheng.com
127.0.0.1 buy.liuqingzheng.com
from flask import Flask, views, url_for
app = Flask(import_name=__name__)
app.config['SERVER_NAME'] = 'liuqingzheng.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"
#可以传入任意的字符串,如传入的字符串为aa,显示为 aa.liuqingzheng.com
@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()
访问:
http://www.liuqingzheng.com:5000/dynamic
http://admin.liuqingzheng.com:5000/dynamic
http://buy.liuqingzheng.com:5000/dynamic
'''
### 可以通过自定义,让路由支持正则(了解)
# 注册路由
# 如果是cbv,as_view(name='xx') name就是别名
#如果endpoint不传,使用函数名字作为endpoint----view
# 优先有endpoint指定的
app.add_url_rule('/index',endpoint='sss',view_func=Index.as_view(name='xx'))
if __name__ == '__main__':
app.run(port=8000)