一 .Flask 配置文件 路由 视图 请求 响应 cookie session 闪现 基础知识(使用)
1.知识点巩固(通过字符串来获取类 类中的属性)
给一个字符串路径来获取 类和类里面的静态属性 app.py import importlib path="settings.Foo" # 给字符串找类 先截取 在通过模块 在通过反射 a,b=path.rsplit(".",maxsplit=1) # 加了maxsplit参数,发现在大量数据处理的时候 print(a,b) # settings Foo m=importlib.import_module(a) print(m) # <module 'settings' from 'J:\django_flask\myflask\settings.py'> cls=getattr(m,b) print(cls) # <class 'settings.Foo'> # 如何找到这个类 print(dir(cls)) # 这个是获取到类里面的所有信息 # ['NAME', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', # '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age'] for key in dir(cls): if key.isupper(): print(key) # 获取类里面值 print(key,getattr(cls,key)) # NAME 张三
settings.py
class Foo(): NAME="张三" age=22
2.配置文件的基本使用( 根据需求调用配置文件)
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.py
from flask import Flask app=Flask(__name__) # 默认配置文件参数 app.config.from_object("settings.Pro") # 线上环境 配置文件 更据业务需求调用配置文件 # app.config.from_object("settings.Dev") # 测试环境 配置文件 print(app.config) #获取 默认配置文件参数 if __name__=="__main__": app.run()
settings.py
class Bases(object): # 公用配置文件 让下面去继承 下面的类就可以调用父类的方法 属性等 age=55 # 配置文件 class Pro(Bases): # 线上环境 配置文件 DUBUG=False class Dev(Bases): # 测试环境 配置文件 DUBUG=True
settings.py
from datetime import timedelta class Config(object): DEBUG = False TESTING = False SECRET_KEY = "asdfasdfas23" DATABASE_URI = 'sqlite://:memory:' 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 PERMANENT_SESSION_LIFETIME = timedelta(hours=1) class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config): DEBUG = True class TestingConfig(Config): TESTING = True
3. 路由(反向解析)
# @app.route('/') #相当于 def hello(): return'xxx' app.add_url_rule('/',view_func=hello) 这个是看源码的原生路由 等同于 @app.route('/')
from flask import Flask,url_for app=Flask(__name__) @app.route("/index/cccc/awqwqwqwwq/",methods=["GET","POST"],endpoint="n1") # endpoint 反向解析 默认写就等于被装饰的函数明 def aa(): print(url_for('n1')) return "路由系统哈哈哈" if __name__=="__main__": app.run()
from flask import Flask,url_for app=Flask(__name__) @app.route("/index/cccc/awqwqwqwwq/",methods=["GET","POST"]) # endpoint 反向解析 默认写就等于被装饰的函数明 def aa(): print(url_for('aa')) return "路由系统哈哈哈" if __name__=="__main__": app.run()
4. 路由(动态和参数 反向解析参数)
from flask import Flask,url_for app=Flask(__name__) @app.route("/index/<int:nid>",methods=["GET","POST"]) # int string float url传参数必须加类型 但是默认是字符串 默认做不了正则 # @app.route("/index/<nid>",methods=["GET","POST"]) # 者默认参数 是字符串类型 def aa(nid): print("这是传进来的参数:",nid) return "路由系统哈哈哈" if __name__=="__main__": app.run()
from flask import Flask,url_for app=Flask(__name__) @app.route("/index/<int:nid>",methods=["GET","POST"]) # int string float url传参数必须加类型 但是默认是字符串 默认做不了正则 # @app.route("/index/<nid>",methods=["GET","POST"]) # 者默认参数 是字符串类型 def aa(nid): print( url_for("aa",nid=5)) # 反向解析传参数 print("这是传进来的参数:",nid) return "路由系统哈哈哈" if __name__=="__main__": app.run()
@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']) 常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理: 9 DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
redirect_to参数 from flask import Flask,render_template,request,redirect app=Flask(__name__) @app.route("/home/",redirect_to="/index/") # redirect_to 保留原来的地址跳转到新的地址(就是原地址跳转新地址) def home(): return "这是home鸭哈哈哈哈" @app.route("/index/") def index(): return "这是index11111111111111111页哈哈哈哈" if __name__ == '__main__': app.run()
from flask import Flask
app = Flask(__name__)
"""
1. 先执行 decorator = app.route('/index')
2. @decorator
"""
@app.route('/index/',endpoint='n1',methods=['GET',"POST"])
def index():
return "index"
@app.route('/new/')
def new():
return "New"
if __name__ == '__main__':
app.run()
用flask实现子域名
flask在注册路由的时候,允许一个参数subdomain
在启动服务前,还需要配置DNS解析
DNS解析,即在访问一个网址时,会将网址映射到一个对应的IP地址上,所以我们 要在本地测试我们的admin.test.com:5000也需要配置我们的DNS解析
以管理员的身份打开C:WindowsSystem32driversetc下面的hosts文件,在最后加入我们希望映射的网址即可
from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'lover.com:5000' # 这个需要在 host 文件添加地址 """ 127.0.0.1 lover.com 127.0.0.1 web.lover.com 127.0.0.1 admin.lover.com """ # http://admin.lover.com:5000/ @app.route("/", subdomain="admin") def admin_index(): return "admin.your-domain.tld" # http://web.lover.com:5000/ @app.route("/", subdomain="web") def web_index(): return "web.your-domain.tld" # http://sdsdf.lover.com:5000/ # http://sdfsdf.lover.com:5000/ # http://asdf.lover.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()
4. 请求(request) 返回值(return 响应体) 定制响应头session
session 是在请求刚进就创建了
from flask import Flask, request,jsonify,json,render_template,redirect app=Flask(__name__) @app.route("/login/",methods=["GET","POST"]) # int string float url传参数必须加类型 但是默认是字符串 默认做不了正则 def login(): # 请求相关信息 aa= 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 redirect() return render_template() dict={"k1":"v1"} return jsonify (dict) # 这个会帮助我们序列化 return "字符串" if __name__=="__main__": app.run()
定制响应头和session
from flask import Flask, request,jsonify,json,render_template,redirect,make_response app=Flask(__name__) @app.route("/login/",methods=["GET","POST"]) # int string float url传参数必须加类型 但是默认是字符串 默认做不了正则 def login(): obj=make_response("哈哈哈哈") 给这个数据设置响应头 obj.headers["555"]="123" obj.set_cookie("key","VUE1") return obj if __name__=="__main__": app.run()
5. Flask session机制(只要设置,在任意请求中都能拿到,无论你拿多少次)
字典中的方法可以在session中使用 session : 当请求刚到来:flask读取cookie中session对应的值: eyJrMiI6NDU2LCJ1c2VyIjoib2xkYm95,将该值解密并反序列化成字典, 放入内存以便视图函数使用。 视图函数: @app.route('/ses') def ses(): session['k1'] = 123 session['k2'] = 456 del session['k1'] return "Session" session['xxx'] = 123 session['xxx'] 当请求结束时, flask会读取内存中字典的值,进行序列化+加密,写入到用户cookie中。
session 一些配置
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 PERMANENT_SESSION_LIFETIME = timedelta(hours=1)
用之前必须先设置秘钥 app.secret_key="asdas" #值随便 使用 from flask import Flask, make_response, request,session app.config['SESSION_COOKIE_NAME']="session_key" #这是配置网页中sessions显示的key @app.route('/') def hello(): session['username'] = 'xxx' #设置 #session本身就是个字典相当于把一个username:xxx键值对丢进去,然后Flask会把整个字典结合secret_key进行加密 #1.生成一个随机的字符串 #2 往数据库存 #3 写入cookie返回浏览器 sessions = session #获取所有session session_username =session['username'] #获取指定session session.pop('username') #删除session原理和字典的删除方式一样 return 'ok'
6. cookie使用
from flask import Flask, make_response, request @app.route('/') def hello(): response = make_response('ok') #先要创建一个response对象 response.set_cookie('key','value') #用set_cookie设置cookies cookies = request.cookies #获取所有cookies且以字典的形式的返回 cookies_key = request.cookies['key'] #因为返回是cookies的字典对象所以我们可以用字典取值取出指定的cookie return response
设置cookie的参数 key, 键 value='', 值 max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是 None`` ,这个cookie会延续到浏览器关闭为止 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。 domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取 secure=False, 浏览器将通过HTTPS来回传cookie httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖) 这些参数全都再app.config中进行设置 '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,
7. 闪现(就是使用 一旦设置,可在任意一次请求中获取 但是只能取一次 基于session)
settings.py from datetime import timedelta class Config(object): DEBUG = False TESTING = False SECRET_KEY = "asdfasdfas23" DATABASE_URI = 'sqlite://:memory:' 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 PERMANENT_SESSION_LIFETIME = timedelta(hours=1) class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config): DEBUG = True class TestingConfig(Config): TESTING = True
闪现(出现一下),在session中存储一个数据,读取时通过pop将数据移除。(使用一次取一次)
from flask import Flask,flash,get_flashed_messages
from flask import Flask,render_template,request,redirect,session,url_for,jsonify,make_response,Markup,flash,get_flashed_messages app=Flask(__name__) app.config.from_object("settings.DevelopmentConfig") @app.route('/aa/') def index(): # session['uuuuu'] = 123 flash('临时数据存储','error') flash('sdfsdf234234','error') flash('adasdfasdf','info') return "Session _index" @app.route('/bb/') def home(): # print(session['uuuuu']) # del session['uuuuu'] # session.pop('uuuuu') print(get_flashed_messages(category_filter=['error'])) return "Session——home" if __name__ == '__main__': app.run()