Flask系列(二)Flask基础
知识点回顾
1、flask依赖wsgi,实现wsgi的模块:wsgiref(django),werkzeug(flask),uwsgi(上线)
2、实例化Flask对象,里面是有参数的
app = Flask(__name__,template_folder='templates',static_url_path='/xxxxxx')
3、两种添加路由的方式
- 方式一:
- @app.route('/xxxx') # @decorator
- def index():
- return "Index"
- 方式二:
- def index():
- return "Index"
- app.add_url_rule('/xxx', "n1", index) #n1是别名
4、添加路由关系的本质
将url和视图函数封装成一个Rule对象)添加到Flask的url_map字段中
5、Flask中装饰器应用
- from flask import Flask,render_template,request,redirect,session
- app = Flask(__name__)
- app.secret_key = "sdsfdsgdfgdfgfh"
- def wrapper(func):
- def inner(*args,**kwargs):
- if not session.get("user_info"):
- return redirect("/login")
- ret = func(*args,**kwargs)
- return ret
- return inner
- @app.route("/login",methods=["GET","POST"])
- def login():
- if request.method=="GET":
- return render_template("login.html")
- else:
- # print(request.values) #这个里面什么都有,相当于body
- username = request.form.get("username")
- password = request.form.get("password")
- if username=="haiyan" and password=="":
- session["user_info"] = username
- # session.pop("user_info") #删除session
- return redirect("/index")
- else:
- # return render_template("login.html",**{"msg":"用户名或密码错误"})
- return render_template("login.html",msg="用户名或者密码错误")
- @app.route("/index",methods=["GET","POST"])
- @wrapper
- def index():
- # if not session.get("user_info"):
- # return redirect("/login")
- return render_template("index.html")
- if __name__ == '__main__':
- app.run(debug=True)
6、请求相关
- request
- request.form #POST请求
- request.args #GET请求 字典形式的
- request.querystring #GET请求,bytes形式的
- response
- return render_tempalte()
- return redirect()
- return ""
v = make_response(返回值) #吧返回的值包在了这个函数里面
- session
- 存在浏览器上,并且是加密的
- 依赖于:secret_key
一、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'] = 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目录
- 配置文件
二、路由系统
1、可传入参数
- @app.route('/user/<username>') #常用的 不加参数的时候默认是字符串形式的
- @app.route('/post/<int:post_id>') #常用的 #指定int,说明是整型的
- @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,
- }
2、反向生成URL
url_for
endpoint("name") #别名,相当于django中的name
反向解析需要导入:
from flask import Flask, url_for
- @app.route('/index',endpoint="xxx") #endpoint是别名
- def index():
- v = url_for("xxx")
- print(v)
- return "index"
- @app.route('/zzz/<int:nid>',endpoint="aaa") #endpoint是别名
- def zzz(nid):
- v = url_for("aaa",nid=nid)
- print(v)
- return "index2"
3、@app.route和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"]
- 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, 重定向到指定地址
- 如:
- @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
- 或
- def func(adapter, nid):
- return "/home/888"
- @app.route('/index/<int:nid>', redirect_to=func)
- subdomain=None, 子域名访问
- from flask import Flask, views, url_for
- app = Flask(import_name=__name__)
- app.config['SERVER_NAME'] = 'haiyan.com:5000'
- @app.route("/", subdomain="admin")
- def static_index():
- """Flask supports static subdomains
- This is available at static.your-domain.tld"""
- return "admin.xxx.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()
- 所有的域名都得与IP做一个域名解析:
- 如果你想通过域名去访问,有两种解决方式:
- 方式一:
- 1、租一个域名 haiyan.lalala
- 2、租一个公网IP 49.8.5.62
- 3、域名解析:
- haiyan.com 49.8.5.62
- 4、吧代码放在49.8.5.62这个服务器上,程序运行起来
- 用户可以通过IP进行访问
- 方式二:如果是自己测试用的就可以用这种方式。先在自己本地的文件中找
- C:\Windows\System32\drivers\etc 找到HOST,修改配置
- 然后吧域名修改成自己的本地服务器127.0.0.1
- 加上配置:app.config["SERVER_NAME"] = "haiyan.com:5000"
练习以上的参数
redirect_to:直接重定向,原url有参数时,跳转是也得传参,注意:不用加类型
- #/old
- @app.route('/old/<int:nid>',redirect_to="/new/<nid>")
- def old(nid):
- return "old"
- # /new
- @app.route('/new/<int:nid>')
- def new(nid):
- return "new"
strict_slashes:对url最后的/符号是否严格要求
- @app.route('/test',strict_slashes=True) #当为True时,url后面必须不加斜杠
- def test():
- return "aaaaaaaa"
- @app.route('/test',strict_slashes=False) #当为False时,url上加不加斜杠都行
- def test():
- return "aaaaaaaa"
subdomain:子域名访问
- @app.route("/static_index", subdomain="admin")
- def static_index():
- return "admin.bjg.com"
subdomain:动态生成子域名
- @app.route("/index",subdomain='<xxxxx>')
- def index(xxxxx):
- return "%s.bjg.com" %(xxxxx,)
扩展Flask的路由系统,让他支持正则,这个类必须这样写,必须去继承BaseConverter
- 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
- # 添加到converts中
- app.url_map.converters['regex'] = RegexConverter
- # 进行使用
- @app.route('/index/<regex("\d+"):nid>',endpoint='xx')
- def index(nid):
- url_for('xx',nid=123) #反向生成,就会去执行to_url方法
- return "Index"
- if __name__ == '__main__':
- app.run()
三、视图
1、diango中的CBV模式
2、Flask中的CBV模式
- def auth(func):
- def inner(*args, **kwargs):
- result = func(*args, **kwargs)
- return result
- return inner
- class IndexView(views.MethodView):
- # methods = ['POST'] #只允许POST请求访问
- decorators = [auth,] #如果想给所有的get,post请求加装饰器,就可以这样来写,也可以单个指定
- def get(self): #如果是get请求需要执行的代码
- v = url_for('index')
- print(v)
- return "GET"
- def post(self): #如果是post请求执行的代码
- return "POST"
- app.add_url_rule('/index', view_func=IndexView.as_view(name='index')) #name指定的是别名,会当做endpoint使用
- if __name__ == '__main__':
- app.run()
3、Flask中的FBV模式
两种方式:
- 方式一:
- @app.route('/index',endpoint='xx')
- def index(nid):
- url_for('xx',nid=123)
- return "Index"
- 方式二:
- def index(nid):
- url_for('xx',nid=123)
- return "Index"
- app.add_url_rule('/index',index)
四、请求与响应
- from flask import Flask
- from flask import request
- from flask import render_template
- from flask import redirect
- from flask import make_response
- app = Flask(__name__)
- @app.route('/login.html', methods=['GET', "POST"])
- def login():
- # 请求相关信息
- # 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 "字符串"
- # return render_template('html模板路径',**{})
- # return redirect('/index.html')
- # response = make_response(render_template('index.html'))
- # response是flask.wrappers.Response类型
- # response.delete_cookie('key')
- # response.set_cookie('key', 'value')
- # response.headers['X-Something'] = 'A value'
- # return response
- return "内容"
- if __name__ == '__main__':
- app.run()
- from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response
- from urllib.parse import urlencode,quote,unquote
- app = Flask(__name__)
- @app.route('/index',endpoint='xx')
- def index():
- from werkzeug.datastructures import ImmutableMultiDict
- =================
- # get_data = request.args
- # get_dict = get_data.to_dict()
- # get_dict['xx'] = '18'
- # url = urlencode(get_dict)
- # print(url)
- ====================
- # print(request.query_string)
- # print(request.args)
- ==========================
- # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
- # print(unquote(val)) #吧上面这样的数据转换成中文
- #
- # return "Index"
- # return "Index"
- # return redirect()
- # return render_template()
- # return jsonify(name='alex',age='18') #相当于JsonResponse
- =======================
- response = make_response('xxxxx') ##如果是返回更多的值,cookie,headers,或者其他的就可用它
- response.headers['xxx'] = ''
- return response
- if __name__ == '__main__':
- # app.__call__
- app.run()
五、模版语法
1、为了防止xss攻击,加了验证,所以页面上显示字符串的形式,解决办法,有两种方式
- 在后端Markup
v5 = Markup("<input type='text' />")
- 在前端
{{ v4|safe }}
2、自定义方法
- def test(a,b):
- return a+b
- @app.route('/index')
- def index():
- return render_template("index2.html",test=test)
- index2.html
- <h1>{{ test(1,2) }}</h1>
3、写一个函数在所有的页面都使用
template_global和template_filter
- @app.template_global()
- def sb(a1, a2):
- return a1 + a2
- @app.template_filter()
- def db(a1, a2, a3):
- return a1 + a2 + a3
调用方式:{{sb(1,2)}} {{ 1|db(2,3)}}
4、模板继承:和django的一样。extents
5、宏:只有定义的东西在很多地方去使用的时候才去用它
- {% macro input(name, type='text', value='') %}
- <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
- {% endmacro %}
- {{ input('n1') }}
6、练习示例:
- from flask import Flask,url_for,render_template,Markup
- app = Flask(__name__)
- def test(a,b):
- return a+b
- @app.template_global()
- def sb(a1, a2):
- return a1 + a2 + 100
- @app.template_filter()
- def db(a1, a2, a3):
- return a1 + a2 + a3
- @app.route('/index')
- def index():
- v1 = "字符串"
- v2 = [11,22,33]
- v3 = {"k1":"v3","sdf":"sdgfgf"}
- v4 = "<input type='text' />"
- v5 = Markup("<input type='text' />")
- return render_template("index2.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)
- if __name__ == '__main__':
- app.run(debug=True)
模板语法
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width">
- <title>Title</title>
- </head>
- <body>
- {{ v1 }}
- <ul>
- {% for foo in v2 %}
- <li>{{ foo }}</li>
- {% endfor %}
- {{ v2.1 }}
- {% for k,v in v3.items() %}
- <li>{{ k }} {{ v }}</li>
- {% endfor %}
- {{ v3.k1 }}
- {{ v3.get("k1") }}
- {{ v4|safe }}
- {{ v5 }}
- <h1>{{ test(1,2) }}</h1>
- <p>{{ sb(1,2) }}</p>
- <p>{{ 1| db(2,3) }}</p>
- </ul>
- </body>
- </html>
index2.html
五、session
除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。
设置:session['username'] = 'xxx'
- 删除:session.pop('username', None)
- from flask import Flask,url_for,session
- app = Flask(__name__)
- app.secret_key = "sdsfdgdgdgd"
- app.config['SESSION_COOKIE_NAME'] = 'session_lvning' #设置session的名字
- @app.route('/index/')
- def index(nid):
- #session本质上操作的是字典, session是否还有其他方法?与字典方法相同
- #session的原理:如果下一次访问的时候带着随机字符串,会把session里面对应的
- # 值拿到内存,假设session保存在数据库,每执行一次链接一次数据库,每次都要时时更新的话
- # 会非常损耗内存
- session["xxx"] = 123
- session["xxx2"] = 123
- session["xxx3"] = 123
- session["xxx4"] = 123
- del session["xxx2"] #在这删除了,真正存储的时候是没有xxx2的
- return "ddsf"
- if __name__ == '__main__':
- app.run()
关于session的配置
app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
- - session超时时间如何设置? 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)
- 以下是跟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(days=31)
- from flask import Flask, session, redirect, url_for, escape, request
- app = Flask(__name__)
- @app.route('/')
- def index():
- if 'username' in session:
- return 'Logged in as %s' % escape(session['username'])
- return 'You are not logged in'
- @app.route('/login', methods=['GET', 'POST'])
- def login():
- if request.method == 'POST':
- session['username'] = request.form['username']
- return redirect(url_for('index'))
- return '''
- <form action="" method="post">
- <p><input type=text name=username>
- <p><input type=submit value=Login>
- </form>
- '''
- @app.route('/logout')
- def logout():
- # remove the username from the session if it's there
- session.pop('username', None)
- return redirect(url_for('index'))
- # set the secret key. keep this really secret:
- app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
基本使用
- pip3 install Flask-Session
- run.py
- from flask import Flask
- from flask import session
- from pro_flask.utils.session import MySessionInterface
- app = Flask(__name__)
- app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
- app.session_interface = MySessionInterface()
- @app.route('/login.html', methods=['GET', "POST"])
- def login():
- print(session)
- session['user1'] = 'alex'
- session['user2'] = 'alex'
- del session['user2']
- return "内容"
- if __name__ == '__main__':
- app.run()
- session.py
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- import uuid
- import json
- from flask.sessions import SessionInterface
- from flask.sessions import SessionMixin
- from itsdangerous import Signer, BadSignature, want_bytes
- class MySession(dict, SessionMixin):
- def __init__(self, initial=None, sid=None):
- self.sid = sid
- self.initial = initial
- super(MySession, self).__init__(initial or ())
- def __setitem__(self, key, value):
- super(MySession, self).__setitem__(key, value)
- def __getitem__(self, item):
- return super(MySession, self).__getitem__(item)
- def __delitem__(self, key):
- super(MySession, self).__delitem__(key)
- class MySessionInterface(SessionInterface):
- session_class = MySession
- container = {}
- def __init__(self):
- import redis
- self.redis = redis.Redis()
- def _generate_sid(self):
- return str(uuid.uuid4())
- def _get_signer(self, app):
- if not app.secret_key:
- return None
- return Signer(app.secret_key, salt='flask-session',
- key_derivation='hmac')
- def open_session(self, app, request):
- """
- 程序刚启动时执行,需要返回一个session对象
- """
- sid = request.cookies.get(app.session_cookie_name)
- if not sid:
- sid = self._generate_sid()
- return self.session_class(sid=sid)
- signer = self._get_signer(app)
- try:
- sid_as_bytes = signer.unsign(sid)
- sid = sid_as_bytes.decode()
- except BadSignature:
- sid = self._generate_sid()
- return self.session_class(sid=sid)
- # session保存在redis中
- # val = self.redis.get(sid)
- # session保存在内存中
- val = self.container.get(sid)
- if val is not None:
- try:
- data = json.loads(val)
- return self.session_class(data, sid=sid)
- except:
- return self.session_class(sid=sid)
- return self.session_class(sid=sid)
- def save_session(self, app, session, response):
- """
- 程序结束前执行,可以保存session中所有的值
- 如:
- 保存到resit
- 写入到用户cookie
- """
- domain = self.get_cookie_domain(app)
- path = self.get_cookie_path(app)
- httponly = self.get_cookie_httponly(app)
- secure = self.get_cookie_secure(app)
- expires = self.get_expiration_time(app, session)
- val = json.dumps(dict(session))
- # session保存在redis中
- # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
- # session保存在内存中
- self.container.setdefault(session.sid, val)
- session_id = self._get_signer(app).sign(want_bytes(session.sid))
- response.set_cookie(app.session_cookie_name, session_id,
- expires=expires, httponly=httponly,
- domain=domain, path=path, secure=secure)
自定义Session
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- """
- pip3 install redis
- pip3 install flask-session
- """
- from flask import Flask, session, redirect
- from flask.ext.session import Session
- app = Flask(__name__)
- app.debug = True
- app.secret_key = 'asdfasdfasd'
- app.config['SESSION_TYPE'] = 'redis'
- from redis import Redis
- app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='')
- Session(app)
- @app.route('/login')
- def login():
- session['username'] = 'alex'
- return redirect('/index')
- @app.route('/index')
- def index():
- name = session['username']
- return name
- if __name__ == '__main__':
- app.run()
第三方session
六、闪现flash
session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了
1、本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅吧值取走,而且吧session里的东西去掉
2、闪现有什么用?
- from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
- app = Flask(__name__)
- app.secret_key ='sdfsdfsdf'
- @app.route('/users')
- def users():
- # 方式一
- # msg = request.args.get('msg','')
- # 方式二
- # msg = session.get('msg')
- # if msg:
- # del session['msg']
- # 方式三
- v = get_flashed_messages()
- print(v)
- msg = ''
- return render_template('users.html',msg=msg)
- @app.route('/useradd')
- def user_add():
- # 在数据库中添加一条数据
- # 假设添加成功,在跳转到列表页面时,显示添加成功
- # 方式一
- # return redirect('/users?msg=添加成功')
- # 方式二
- # session['msg'] = '添加成功'
- # 方式三
- flash('添加成功')
- return redirect('/users')
- if __name__ == '__main__':
- app.run(debug=True)
七、扩展
1、在函数执行之前或函数执行之后做点事情
第一种:装饰器
第二种:flask里面的扩展,相当于django中的中间件
- from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
- app = Flask(__name__)
- app.secret_key ='sdfsdfsdf'
- @app.before_request
- def process_request1():
- print('process_request1')
- @app.after_request
- def process_response1(response):
- print('process_response1')
- return response
- @app.before_request
- def process_request2():
- print('process_request2')
- @app.after_request
- def process_response2(response): #参数也得有
- print('process_response2')
- return response #必须有返回值
- @app.route('/index')
- def index():
- print('index')
- return 'Index'
- @app.route('/order')
- def order():
- print('order')
- return 'order'
- @app.route('/test')
- def test():
- print('test')
- return 'test'
- if __name__ == '__main__':
- app.run()
运行结果:
还有一个@app.before_first_request:表示,当程序运行起来,第一个请求来的时候就只执行一次,下次再来就不会在执行了
Flask系列(二)Flask基础的更多相关文章
- flask系列二之基础知识
一.调试模式(debug模式) 1.设置debug模式 在app.run()中传入关键字参数debug,app.run(debug=Ture),就设置当前项目为debug模式.如下所示: # 从fla ...
- Mina 系列(二)之基础
Mina 系列(二)之基础 Mina 使用起来多么简洁方便呀,就是不具备 Java NIO 的基础,只要了解 Mina 常用的 API,就可以灵活使用并完成应用开发. 1. Mina 概述 首先,看 ...
- Flask系列(六)Flask实例化补充及信号
一.实例化补充 instance_path和instance_relative_config是配合来用的. 这两个参数是用来找配置文件的,当用app.config.from_pyfile('setti ...
- Flask系列06--(中间件)Flask的特殊装饰器 before_request,after_request, errorhandler
一.使用 Flask中的特殊装饰器(中间件)方法常用的有三个 @app.before_request # 在请求进入视图函数之前 @app.after_request # 在请求结束视图函数之后 响应 ...
- Flask系列(五)Flask实现分页
一.flask分页组件 from urllib.parse import urlencode,quote,unquote class Pagination(object): ""& ...
- Flask系列(四)Flask实现简单页面登陆
from flask import Flask,render_template,request,redirect,session app = Flask(__name__,template_folde ...
- Elasticsearch学习系列二(基础操作)
本文将分为3块讲解Es的基础操作.分别为:索引(index).映射(mapping).文档(document). 索引操作 创建索引库 语法: PUT /索引名称{ "settings&qu ...
- Flask系列10-- Flask请求上下文源码分析
总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...
- 【Python】Flask系列-URL和视图笔记
1.学习目标 熟悉Flask相关知识. 熟悉web开发流程. 能独立开发Flask项目. 2.环境配置 Python虚拟环境安装 因为python的框架更新迭代太快了,有时候需要在电脑上存在一个框架的 ...
随机推荐
- NFS挂在文件系统启动参数
1.tiny6410(增强版)bootargs启动参数(周学伟)noinitrd console=ttySAC0,115200 lcd=S70 init=/init root=/dev/nfs rw ...
- CreateEvent和SetEvent及WaitForSingleObject的使用方法
CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttri ...
- swift - 利用UIDatePicker实现定时器的效果
效果图如下: 可以通过UIDatePicker调整倒计时的时间,然后点击UIButton开始倒计时,使用NSTimer进行倒计时的时间展示,我是声明了一个label也进行了标记, 然后点击按钮开始倒计 ...
- Android Tab切换
ViewPager+FragmentStatePagerAdapter 页面切换案例详解 http://blog.csdn.net/u010203181/article/details/4462963 ...
- Nginx(二)-- 配置文件之虚拟主机配置
1.配置文件与解释 #user nobody; worker_processes 1; # 设置工作子进程,默认是1个工作子进程,可以修改,一般设置为CPU的总核数 #error_log logs/e ...
- Unity随机Prefab,自动前往某点处理
对与U3D AI,看了下,自己做了小功能,以备后用啊! 一,在某区域随机产生某个对象 C# 文件名称为RadomAPoint.cs using UnityEngine; using System.C ...
- JavaBean入门及简单的例子
不会编写JavaBean就不是一个Java开发人员. 那么,何谓JavaBean呢? JavaBean是符合某种规范的Java组件,也就是Java类. 它必须满足如下规范: 1)必须有一个零参数的默认 ...
- Html5 拖拽行为和AngularJs的结合
一. Html5的拖拽行为 1.设置元素为可拖放:把draggable属性设置为true. example: <div id="drag1" draggable=" ...
- Egret Wing4.1.0 断点调试
一 双击代码行号左侧打断点 二 选择调试视图工具栏. 三 点击开始调试 1 wing内置播放器调试 选择此项进行调试会打开Egret内置播放器,我这里这个版本该选项无法进行断点... 2 使用本机 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...