当前位置: 首页 > news >正文

视频投票网站怎么做的创意上海专业网站建设

视频投票网站怎么做的,创意上海专业网站建设,做花型设计哪个网站下载素材好,桂林北站附近有什么好玩的一、Python之flask、Django、Tornado框架 一#xff09;django 主要是用来搞快速开发的#xff0c;他的亮点就是快速开发#xff0c;节约成本。 正常的并发量不过10000#xff0c;如果要实现高并发的话#xff0c;就要对django进行二次开发#xff0c;比如把整个笨重的框… 一、Python之flask、Django、Tornado框架 一django 主要是用来搞快速开发的他的亮点就是快速开发节约成本。 正常的并发量不过10000如果要实现高并发的话就要对django进行二次开发比如把整个笨重的框架给拆掉自己写socket实现http的通信底层用纯cc写提升效率ORM框架给干掉自己编写封装与数据库交互的框 架ORM虽然面向对象来操作数据库但是它的效率很低使用外键来联系表与表之间的查询 二flask 轻量级主要是用来写接口的一个框架实现前后端分离提升开发效率。第三方组件非常丰富。Flask本身相当于一个内核其他几乎所有的功能都要用到扩展邮件扩展Flask-Mail用户认证Flask-Login都需要用第三方的扩展来实现。 路由比较特殊基于装饰器来实现但是究其本质还是通过add_url_rule来实现。 比如可以用Flask-extension加入ORM、窗体验证工具文件上传、身份验 证等。Flask没有默认使用的数据库你可以选择MySQL也可以NoSQL。 WSGI 工具箱采用 Werkzeug路由模块模板引擎则使用 Jinja2。这两个也是Flask框架的核心。 Python最出名的框架要数Django此外还有Flask、Tornado等框架。 虽然Flask不是最出名的框架但是Flask应该算是最灵活的框架之一这也是Flask受到广大开发者喜爱的原因。 三Tornado Tornado是一种 Web 服务器软件的开源版本。异步非阻塞框架 Tornado 和现在的主流 Web 服务器框架包括大多数 Python 的框架有着明显的区别它是非阻塞式服务器而且速度相当快。 得利于其非阻塞的方式和对epoll的运用Tornado 每秒可以处理数以千计的连接因此 Tornado 是实时 Web 服务的一个 理想框架。 二、Flask基础学习 一flask入门 官网https://flask.palletsprojects.com/en/1.1.x/ 中文文档https://dormousehole.readthedocs.io/en/latest/ Flask 概述_w3cschool 1、项目结构 web项目MVC model  模型 view     视图 controller 控制器 pythonMTV model  模型 templates  模板----%html view  视图起控制作用 2、flask常用三方组件 官方插件Search results · PyPI 常用三方组件flask常用组件 - 简书 3、安装flask pip3 install flask pip3 install pymysql  #连接mysql pip3 install flask-sqlalchemy # 实现ORM映射 pip3 install flask-migrate #发布命令工具 pip3 install flask_scripts # 管理工具 4、基本使用 from flask import Flask # 实例化Flask对象 app Flask(__name__) # 将/和函数index的对应关系添加到路由中{/:index }app.route(/) def hello_world():return Hello World!if __name__ __main__: #监听用户请求 #若有用户请求到来则执行app的__call__方法 #app.__call__app.run() 1参数 初始化参数 import_namestatic_url_pathstatic_folder 默认是项目根路径下的statictemplate_folder 默认是项目根目录下的templates 2外部可见的服务器 运行服务器后会发现只有您自己的电脑可以使用服务而网络中的其他电脑却 不行。缺省设置就是这样的因为在调试模式下该应用的用户可以执行您电脑中 的任意 Python 代码。 终端启动 如果您关闭了调试器或信任您网络中的用户那么可以让服务器被公开访问。 只要在命令行上简单的加上 --host0.0.0.0 即可: 说明 环境变量FLASK_APP知名flask的启动实例flask run -h 0.0.0.0 -p 8000  绑定地址和端口flask run --help 获取帮助通过FLASK_ENV 环境变量指明 export FLASK_ENVproduction 运行生产模式未指明则默认为此方式export FLASK_ENVdevelopment 运行开发模式 flask run --host0.0.0.0 --port5001 在代码里指定 if __name__ __main__:app.run(host0.0.0.0,port5000) 5、secret_key  1什么是SECRET_KEY Flask中有个配置属性叫做SECRET_KEY 2secret_key 的作用 Flask以及相关的扩展extension需要进行加密 所以需要这个密钥SECRET_KEY - 之所以需要加密是因为有些涉及到安全的东西需要加密 3需要加密的东西 执行代码报错解决问题的方法——引用secret_key Internal Server Error The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application. Flask本身相关的有session 其它一些第三方的库相关的有 Flask-Images内部可能是图片处理用到的Cookies相关的Flask-WTF的CSRF保护 二配置文件 工程配置参数 app.config.from_object(配置对象) 继承 —— 优点可以复用缺点敏感数据暴露app.config.from_pyfile(配置文件) 优点独立文件保护敏感数据缺点不能继承文件路径固定不灵活app.config.from_envvar(‘环境变量名’) 优点独立文件保护敏感数据 文件路径不固定灵活缺点不方便要记得设置环境变量设置环境变量方式 系统终端设置exportpycharm 设置 1、默认的配置 flask中的配置文件是一个flask.config.Config对象继承字典,默认配置为 {DEBUG: get_debug_flag(defaultFalse), 是否开启Debug模式TESTING: False, 是否开启测试模式PROPAGATE_EXCEPTIONS: None, PRESERVE_CONTEXT_ON_EXCEPTION: None,SECRET_KEY: None,PERMANENT_SESSION_LIFETIME: timedelta(days31),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(hours12),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,} 2、增加和变更配置 1、方式一直接写在代码文件中 app.debug True # 或者写成这样 app.config[debug] True app.secret_key aaaacccddd 2、方式二 settings.py 一般在项目根路径下 #####写到单独的文件settings.py中 app.config.from_pyfile(python文件名称)如settings.pyDEBUG Trueapp.config.from_pyfile(settings.py)app.config.from_envvar(环境变量名称)环境变量的值为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.pyclass Config(object):DEBUG FalseTESTING FalseDATABASE_URI sqlite://:memory:SQLALCGEMY_DATABASE_URL mysqlpymysql://root127.0.0.1:3306/flaskstudyclass ProductionConfig(Config):DATABASE_URI mysql://userlocalhost/fooclass DevelopmentConfig(Config):DEBUG Trueclass TestingConfig(Config):TESTING TruePS: 从sys.path中已经存在路径开始写PS: settings.py文件默认路径要放在程序root_path目录如果instance_relative_config为True则就是instance_path目录 三路由系统 1、查看路由信息 命令行方法 flask routes在程序中获取 在应用中url_map属性中保存着整个Flask应用的路由映射信息可以通过读取这个属性获取路由信息 print(app.url_map) 若想在程序中遍历路由信息可以采用如下方式 for rule in app.url_map.iter_rules():print(name{} path{}.format(rule.endpoint, rule.rule)) 2、请求方式 GETOPTIONS自带——简化版的GET请求用于询问服务器接口信息的比如接口允许的请求方式允许的请求源头域名 CORS跨域 Django-cors——中间件中拦截处理了options请求HEAD自带简化版的GET请求 只返回GET请求处理时的响应头不返回响应体POSTPUTDELETEPATCH 3、常见的路由系统 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, } 动态路由 1HTML转义 当返回 HTML Flask 中的默认响应类型时为了防止注入攻击所有用户提 供的值在输出渲染前必须被转义。使用 Jinja 这个稍后会介绍渲染的 HTML 模板会自动执行此操作。 在下面展示的 escape() 可以手动转义。因为保持简洁的原 因在多数示例中它被省略了但您应该始终留心处理不可信的数据。 from flask import Flask from markupsafe import escapeapp Flask(__name__) app.route(/name) def hello(name):return fHello, {escape(name)}! 如果一个用户想要提交其名称为 scriptalert(bad)/script 那么 宁可转义为文本也好过在浏览器中执行脚本。 路由中的 name 从 URL 中捕获值并将其传递给视图函数 2变量规则 通过把 URL 的一部分标记为 variable_name 就可以在 URL 中添加变量。标记的 部分会作为关键字参数传递给函数。 通过使用 converter:variable_name 可以 选择性的加上一个转换器为变量指定规则。请看下面的例子: # -*- coding: utf-8 -*- # Time : 2021/7/15 10:12 # Author : wzs # File : flask_v1.pyfrom flask import Flask from markupsafe import escapeapp Flask(__name__)app.debug True FLASK_ENV development from markupsafe import escapeapp.route(/user/username) def show_user_profile(username):# show the user profile for that userreturn fUser {escape(username)}app.route(/post/int:post_id) def show_post(post_id):# show the post with the given id, the id is an integerreturn fPost {post_id}app.route(/path/path:subpath) def show_subpath(subpath):# show the subpath after /path/return fSubpath {escape(subpath)}if __name__ __main__: #监听用户请求 #若有用户请求到来则执行app的__call__方法 #app.__call__app.run(host0.0.0.0,port5000) string 缺省值 接受任何不包含斜杠的文本 int 接受正整数 float 接受正浮点数 path 类似 string 但可以包含斜杠 uuid 接受 UUID 字符串 app.route(/projects/) def projects():return The project pageapp.route(/about) def about():return The about page projects 的 URL 是中规中矩的尾部有一个斜杠看起来就如同一个文件 夹。访问一个没有斜杠结尾的 URL  /projects 时 Flask 会自动进行重 定向帮您在尾部加上一个斜杠 /projects/ 。 about 的 URL 没有尾部斜杠因此其行为表现与一个文件类似。如果访问这 个 URL 时添加了尾部斜杠 /about/ 就会得到一个 404 “未找到” 错 误。这样可以保持 URL 唯一并有助于搜索引擎重复索引同一页面。 4、注册路由原理 装饰器 urlmethodendpoint url_for def auth(func):def inner(*args, **kwargs):print(before)result func(*args, **kwargs)print(after)return resultreturn innerapp.route(/index.html,methods[GET,POST],endpointindex)authdef index():return Index或def index():return Indexself.add_url_rule(rule/index.html, endpointindex, view_funcindex, methods[GET,POST])orapp.add_url_rule(rule/index.html, endpointindex, view_funcindex, methods[GET,POST])app.view_functions[index] index或def auth(func):def inner(*args, **kwargs):print(before)result func(*args, **kwargs)print(after)return resultreturn innerclass IndexView(views.View):methods [GET]decorators [auth, ]def dispatch_request(self):print(Index)return Index!app.add_url_rule(/index, view_funcIndexView.as_view(nameindex)) # nameendpoint或class IndexView(views.MethodView):methods [GET]decorators [auth, ]def get(self):return Index.GETdef post(self):return Index.POSTapp.add_url_rule(/index, view_funcIndexView.as_view(nameindex)) # nameendpointapp.route和app.add_url_rule参数rule, URL规则view_func, 视图函数名称defaultsNone, 默认值,当URL中无参数函数需要参数时使用defaults{k:v}为函数提供参数endpointNone, 名称用于反向生成URL即 url_for(名称)methodsNone, 允许的请求方式如[GET,POST]strict_slashesNone, 对URL最后的 / 符号是否严格要求如app.route(/index,strict_slashesFalse)访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可app.route(/index,strict_slashesTrue)仅访问 http://www.xx.com/index 重定向新功能上线后老地址无法访问 redirect_toNone, 重定向到指定地址如app.route(/index/int:nid, redirect_to/home/nid)或def func(adapter, nid):return /home/888app.route(/index/int:nid, redirect_tofunc)范例from flask import Flaskapp Flask(__name__) app.debug True# 公司老新首页跳转app.route(/index,methods[GET,POST],endpointn1,redirect_to/index2) def index():return 公司老首页app.route(/index2,methods[GET,POST],endpointn2) def index2():return 公司新首页if __name__ __main__:app.run() 子域名 subdomainNone, 子域名访问from flask import Flask, views, url_forapp Flask(import_name__name__)app.config[SERVER_NAME] ops.com:5000app.route(/, subdomainadmin)def static_index():Flask supports static subdomainsThis is available at static.your-domain.tldreturn static.your-domain.tldapp.route(/dynamic, subdomainusername)def username_index(username):Dynamic subdomains are also supportedTry going to user1.your-domain.tld/dynamicreturn username .your-domain.tldif __name__ __main__:app.run() 5、自定义转换器正则路由匹配 regex名字固定 from flask import Flask, views, url_for from werkzeug.routing import BaseConverterapp Flask(import_name__name__)class RegexConverter(BaseConverter):第一步自定义URL匹配正则表达式def __init__(self, map, regex):super(RegexConverter, self).__init__(map)self.regex regexdef 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# 第三步zai app.route(/index/regex(\d):nid) def index(nid):print(url_for(index, nid888))return Indexif __name__ __main__:app.run() Mobile转换器 from flask import Flask from werkzeug.routing import BaseConverterapp Flask(__name__) app.debug True # /user/123 # app.route(/users/user_id) # 等价于 # app.route(/users/string:user_id) app.route(/users/int:user_id)def get_users_data(user_id):print(type(user_id))return get users {}.format(user_id)# 定义转换器 class MobileConverter(BaseConverter):regex r1[3-9]\d{9}# 将自定义转换器告知Flask应用 app.url_map.converters[mobile] MobileConverter# 在使用转换器的地方定义使用 app.route(/sms_code/mobile:mob_num) def send_sms_code(mob_num):print(type(mob_num))# return send sms code to {}.format(mob_num)return fsend sms code to {mob_num}if __name__ __main__:app.run() 四模板template 1、模板的使用 Flask使用的是Jinja2模板所以其语法与Django无差别 2、自定义模板方法 Flask中自定义模板方法的方式和Bottle相似创建一个函数并通过函数形式传入render_template 防XSS攻击若想标记它时前使用 |safe后端使用Markup 注意Markup等价django的mark_safe 1)后端代码 from flask import Flask,render_template,Markup app Flask(__name__) app.debug True def func1(arg): return Markup(input typetext value%s / %(arg,)) app.route(/) def index(): return render_template(s7.html, ff func1) # return render_template(s7.html, **data) # 所有数据 if __name__ __main__: app.run() 2前端代码 !DOCTYPE html html langen headmeta charsetUTF-8titleTitle/title /head body{{ ff(侠客)|safe }} /body /html 3宏定义 !DOCTYPE html html langen headmeta charsetUTF-8titleTitle/title /head body{% macro input(name, typetext, value) %}input type{{ type }} name{{ name }} value{{ value }}{% endmacro %}{{ input(n1) }}{% include tp.html %}h1asdf{{ v.k1}}/h1 /body /html 五请求和响应 1、需求 在视图编写中需要读取客户端请求携带的数据时如何才能正确的取出数据呢 请求携带的数据可能出现在HTTP报文中的不同位置需要使用不同的方法来获取参数。 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 字符串# 返回模板 render_template# return render_template(html模板路径,**{})# 重定向redirect# return redirect(/index.html)# body 返回JSON 的简便方法 jsonify 一、原来的操作 import json return json.dumps({}) # 返回的还是文本二、flask的jsonify return josonify # 1 转换成json格式化字符串 # 2 设置了响应头Content-Type: application/json # 可以返回一个元组这样的元组必须是(response, status, headers)的形式且至少包含一个元素。status值会覆盖状态代码headers可以是一个列表或字典作为额外的消息标头值 # return 状态码为 666, 666, {Itcast:Python}# 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 responsereturn 内容if __name__ __main__:app.run() 六cookie和session 1、cookie #!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ wzs #2021/7/16from flask import Flask, make_response, requestapp Flask(__name__)app.route(/cookie) def set_cookie():resp make_response(set cookie ok)# 设置有效期resp.set_cookie(username, wzs, max_age 3600)return respapp.route(/get_cookie) def ger_cookie():res request.cookies.get(username)return resapp.route(/delete_cookie) def delete_cookie():respose make_response(delete cookie ok)respose.delete_cookie(username)return resposeif __name__ __main__:app.run(port5001, debugTrue) 2、session的使用 除请求对象之外还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的并且对 Cookies 进行密钥签名要使用会话你需要设置一个密钥。 设置session[username] xxx删除session.pop(username, None) 1基本使用 from flask import Flask, session, redirect, url_for, escape, requestapp Flask(__name__)app.route(/) def index():if username in session:return Logged in as %s % escape(session[username])return You are not logged inapp.route(/login, methods[GET, POST]) def login():if request.method POST:session[username] request.form[username]return redirect(url_for(index))return form action methodpostpinput typetext nameusernamepinput typesubmit valueLogin/formapp.route(/logout) def logout():# remove the username from the session if its theresession.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 2自定义session pip3 install Flask-Sessionrun.pyfrom flask import Flaskfrom flask import sessionfrom pro_flask.utils.session import MySessionInterfaceapp Flask(__name__)app.secret_key A0Zr98j/3yX R~XHH!jmN]LWX/,?RTapp.session_interface MySessionInterface()app.route(/login.html, methods[GET, POST])def login():print(session)session[user1] alexsession[user2] alexdel session[user2]return 内容if __name__ __main__:app.run()session.py#!/usr/bin/env python# -*- coding:utf-8 -*-import uuidimport jsonfrom flask.sessions import SessionInterfacefrom flask.sessions import SessionMixinfrom itsdangerous import Signer, BadSignature, want_bytesclass MySession(dict, SessionMixin):def __init__(self, initialNone, sidNone):self.sid sidself.initial initialsuper(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 MySessioncontainer {}def __init__(self):import redisself.redis redis.Redis()def _generate_sid(self):return str(uuid.uuid4())def _get_signer(self, app):if not app.secret_key:return Nonereturn Signer(app.secret_key, saltflask-session,key_derivationhmac)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(sidsid)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(sidsid)# 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, sidsid)except:return self.session_class(sidsid)return self.session_class(sidsid)def save_session(self, app, session, response):程序结束前执行可以保存session中所有的值如保存到resit写入到用户cookiedomain 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(namesession.sid, valueval, timeapp.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,expiresexpires, httponlyhttponly,domaindomain, pathpath, securesecure) 3第三方session #!/usr/bin/env python # -*- coding:utf-8 -*-pip3 install redis pip3 install flask-sessionfrom flask import Flask, session, redirect from flask.ext.session import Sessionapp Flask(__name__) app.debug True app.secret_key asdfasdfasdapp.config[SESSION_TYPE] redis from redis import Redis app.config[SESSION_REDIS] Redis(host192.168.0.94,port6379) Session(app)app.route(/login) def login():session[username] alexreturn redirect(/index)app.route(/index) def index():name session[username]return nameif __name__ __main__:app.run()七message闪现 message是一个基于Session实现的用于保存数据的集合其特点是使用一次就删除。 应用对临时数据操作如显示错误信息 1、基本实现 from flask import Flask,flash,get_flashed_messagesapp Flask(__name__) # app.secret_key ahhjhh227app.route(/get) def get():# 从某个地方获取设置过的所有值并清除data get_flashed_messages()print(data)return getapp.route(/set) def set():# 向某个地方设置一个值flash(维纳斯)return setif __name__ __main__:app.run() 2、实现url错误跳转 session基于用户隔离的不会发生数据错乱 基于session实现的 from flask import Flask,flash,get_flashed_messages,request,redirectapp Flask(__name__) app.secret_key ahhjhh227# 需求当遇到错误时返回错误信息 app.route(/index) def index():# 从某个地方获取设置过的所有值并清除val request.args.get(v)if val ops:return indexflash(超时错误,categoryx1) #取指定信息return redirect(/error)app.route(/error) def error():# 向某个地方设置一个值展示错误信息:return:data get_flashed_messages(category_filter[x1])if data:msg data[0]else:msg ...return 错误信息: %s %(msg,)if __name__ __main__:app.run()八蓝图blueprint 1、需求 在一个Flask应用项目中若业务视图过多可否将以某种方式划分出的业务单元单独维护将每个单元用到的视图、静态文件、模板文件等独立分开 例如从业务角度上可将整个应用划分为用户模块单元、商品模块单元、订单模块单元如何分别开发这些不同单元并最终整合到一个项目应用中 2、蓝图简简述 在Flask中使用蓝图blueprint来分模块组织管理 蓝图实例可以理解为是一个存储一组视图方法的容器对象其具有如下特点 一个应用可以具有多个blueprint可以将一个blueprint注册到任何一个未使用的URL下比如 /usr/goodsblueprint可以单独具有自己模板、静态文件或其他通用操作方法它并不适合必须要应用的视图和函数的在一个应用初始化时就应该要注册需要使用的blueprint 但是一个blueprint并不是一个完整的应用它不能独立于应用运行而必须要注册到某一应用中 3、使用方式 1使用蓝图的三个步骤 创建一个蓝图对象 user_bp Blueprint(user, __name__) 在这个蓝图对象上进行操作注册路由指定静态文件夹注册模板过滤器 user_bp.route(/profile) def get_profile():return user profile 在应用对象上注册这个蓝图对象 app.register_blueprint(user_bp) 2单文件蓝图对象 可以将创建蓝图对象与定义视图放在一个文件中 3目录包蓝图对象 对于一个打算包含一个文件的蓝图通常将创建蓝图对象放到Python包的__init__.py文件中 4、目标构造程序目录 蓝图的包放在__init__.py文件中 批量url模板路径、静态文件路径请求扩展 针对APP针对某个蓝图 5、蓝图用于为应用提供目录划分 小型应用程序示例 大型应用程序示例 1扩展用法 蓝图URL前缀xxx Blueprint(account, __name__,url_prefix/xxx)蓝图子域名xxx Blueprint(account, __name__,subdomainadmin) # 前提需要给配置SERVER_NAME app.config[SERVER_NAME] ops.com:5000 # 访问时admin.ops.com:5000/login.html蓝图内部静态文件目录 和应用对应不同蓝图对象创建时不会默认注册静态目录的路由。需要我们在创建时制定static_folder参数 admin Blueprint(admin, __name__, static_folderstatic_admin) 蓝图内部的模板文件目录 admin Blueprint(admin, __name__, template_foldertemplate_admin6、应用设计的选择 一个应用程序蓝图小型应用程序N个应用程序蓝图大型应用程序 蓝图名称要和函数名称重复 7、问题说明 导入视图放到最后的原因 循环引用 views.py from . import goods_bpgoods_bp.route(/goods) def get_goods():return get goods __init__.py from flask import Blueprint# 创建蓝图对象 goods_bp Blueprint(goods, __name__)from . import views #此处 Flask Debug模式的作用 支持静态文件后端出现错误会直接返回真实的错误信息给前端修改代码后自动重启开发服务器 支持options请求不等价于实现CORS跨域解决方案  九请求钩子(中间层/件) 请求的处理过程pre_process - view - after_process request请求支持处理流程m1.pre_process() - m2.pre_process()  - m3.pre_process()   - view - m3.after_process - m2.after_process - m1.after_process 中间件处理 不区分具体是哪个视图对所有视图通通生效 在客户端和服务器交互的过程中有些准备工作或扫尾工作需要处理比如 在请求开始时建立数据库连接在请求开始时根据需求进行权限校验在请求结束时指定数据的交互格式 为了让每个视图函数避免编写重复功能的代码Flask通过了通用设施的功能即请求钩子 请求钩子是通过装饰器的形式实现Flask支持如下四种请求钩子 before_first_request 在处理第一个请求前执行before_request 在每次请求前执行若在某装饰的函数中返回了一个响应视图函数将不再被调用after_request 若没有抛出错误在每次请求后执行接受一个参数视图函数做出的响应在此函数中可以对响应值在返回之前做最后一步修改处理需要将参数中的响应在此参数中进行返回teardown_request 在每次请求后执行接受一个参数错误信息若有相关错误抛出 1、基于before_request做用户登录认证 from flask import Flask,request,session,redirectapp Flask(__name__) app.before_request def process_request(*args, **kwargs):if request.path /login:return Noneuser session.get(user_info)if user:return Nonereturn redirect(/login) 2、执行顺序 from flask import Flaskapp Flask(__name__)app.debug True app.secret_key suhdjakjdshapp.before_request def process_request1(*args, **kwargs):print(process_request1进来了)return 拦截 app.before_request def process_request2(*args, **kwargs):print(process_request2进来了)app.after_request def process_response1(response):print(process_response1走了)return responseapp.after_request def process_response2(response):print(process_response2走了)return response# 自定义错误 app.errorhandler(404) def error(arg):return 404错误了app.route(/index,methods[GET]) def index():print(index函数)return indexif __name__ __main__:app.run() 3、请求拦截后response都执行 from flask import Flaskapp Flask(__name__)app.debug True app.secret_key suhdjakjdshapp.before_request def process_request1(*args, **kwargs):print(process_request1进来了)return 拦截 app.before_request def process_request2(*args, **kwargs):print(process_request2进来了)app.after_request def process_response1(response):print(process_response1走了)return responseapp.after_request def process_response2(response):print(process_response2走了)return responseapp.route(/index,methods[GET]) def index():print(index函数)return indexif __name__ __main__:app.run() 4、异常处理自定义错误 1HTTP异常主动抛出 abort 方法 抛出一个给定状态代码的HTTPException或者指定响应例如想要一个页面未找到异常来终止请求你可以调用abort(404)参数 code - HTTP的错误状态码只能抛出HTTP协议的错误状态码 2捕获错误 errorhandler 装饰器 注册一个错误处理程序当程序抛出指定错误状态码时就会调用该装饰器所装饰的方法参数 code_or_exception - HTTP 的错误状态码或指定异常 app.errorhandler(500) def internal_server_error(e):return 服务器搬家了# 捕获指定异常app.errorhandler(ZeroDivisionError) def zero_division_error(e):return 除数不能为0 # 自定义错误 app.errorhandler(404) def error(arg):return 404错误了 5、模板函数 调用方式{{sb(1,2)}} {{ 1|db(2,3)}} #!/usr/bin/env python # -*- coding:utf-8 -*- from flask import Flask, Request, render_templateapp Flask(__name__, template_foldertemplates) app.debug Trueapp.before_first_request def before_first_request1():print(before_first_request1)app.before_first_request def before_first_request2():print(before_first_request2)app.before_request def before_request1():Request.nnn 123print(before_request1)app.before_request def before_request2():print(before_request2)app.after_request def after_request1(response):print(before_request1, response)return responseapp.after_request def after_request2(response):print(before_request2, response)return responseapp.errorhandler(404) def page_not_found(error):return This page does not exist, 404app.template_global() def sb(a1, a2):return a1 a2app.template_filter() def db(a1, a2, a3):return a1 a2 a3app.route(/) def hello_world():return render_template(hello.html)if __name__ __main__:app.run() 十上下文管理 上下文即语境语意在程序中可以理解为在代码执行到某一时刻时根据之前代码所做的操作以及山该文即将要执行的逻辑可以决定在当前时刻下可以使用到的变量或者可以完成的事情。 Flask中有两种上下文请求上下文和应用上下文。 Flask中上下文对象相当于一个容器保存了Flask程序运行过程中的一些信息。 1、请求上下文request context 思考在视图函数中如何取到当前请求的相关数据比如请求地址请求方式cookie等等 在flask中可以直接在视图函数中使用request这个对象进行获取相关数据而request就是请求上下文的对象保存了当前本次请求的相关数据请求上下文对象有request、session request 封装了HTTP请求的内容针对的是http请求。举例userrequest.args.get(user)获取的是get请求参数session 用来记录请求会话的信息针对的是用户信息。举例session[name]user.id可以记录用户信息。还可以通过session.get(name)获取用户信息 2、应用上下文application context 字面上是应用上下文但它不是一直存在的它只是request context中的一个对app的代理所谓的local proxy。 应用上下文的作用主要是帮助request获取当前的应用。 应用上下文对象有current_appg 1current_app 应用程序上下文用于存储应用程序中的变量可以通过current_app.name打印当前app的名称也可以在current_app中存储一些变量例如 应用的启动脚本是哪个文件启动时指定了哪些参数加载了哪些配置文件导入了哪些配置连了哪些数据库在哪些public的工具类、常量应用跑在哪个机器上IP多少内存多大 作用current_app 就是当前运行的flask app在代码不方便直接操作flask的对象时可以操作current_app就等价于操作flask app对象 2g对象 g作为flask程序全局的一个临时变量充当中间媒介的作用我们可以通过它在一个请求调用的多个函数间传递一些数据。每次请求都会重设这个变量 #!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ wzs #2021/7/17from flask import Flask, gapp Flask(__name__)def db_query():user_id g.user_iduser_name g.user_nameprint(fuser_id{user_id} user_name{user_name})app.route(/) def get_user_profile():g.user_id 123g.user_name wzsdb_query()return you are great!if __name__ __main__:app.run() 3、上下文实现的原理 Threadlocal 线程局部变量 from flask import request request -全局变量 threading.local 对象用于为每个线程开辟一块空间来保存它独有的值 1现状三种情况 单进程单线程基于全局变量做单进程多线程threading.local对象单进程单线程多协程threading.local对象做不到 2对此现状的抉择 以后不支持协程threading.local对象支持自定义类似threading.local对象支持协程 3自定义类似threading.local对象 greenlet import getcurrent as get_ident from greenlet import getcurrent as get_identdef release_local(local):local.__release_local__()class Local(object):__slots__ (__storage__, __ident_func__)def __init__(self):# self.__storage__ {}# self.__ident_func__ get_identobject.__setattr__(self, __storage__, {})object.__setattr__(self, __ident_func__, get_ident)def __release_local__(self):self.__storage__.pop(self.__ident_func__(), None)def __getattr__(self, name):try:return self.__storage__[self.__ident_func__()][name]except KeyError:raise AttributeError(name)def __setattr__(self, name, value):ident self.__ident_func__()storage self.__storage__try:storage[ident][name] valueexcept KeyError:storage[ident] {name: value}def __delattr__(self, name):try:del self.__storage__[self.__ident_func__()][name]except KeyError:raise AttributeError(name)class LocalStack(object):def __init__(self):self._local Local()def __release_local__(self):self._local.__release_local__()def push(self, obj):Pushes a new item to the stackrv getattr(self._local, stack, None)if rv is None:self._local.stack rv []rv.append(obj)return rvdef pop(self):Removes the topmost item from the stack, will return theold value or None if the stack was already empty.stack getattr(self._local, stack, None)if stack is None:return Noneelif len(stack) 1:release_local(self._local)return stack[-1]else:return stack.pop()propertydef top(self):The topmost item on the stack. If the stack is empty,None is returned.try:return self._local.stack[-1]except (AttributeError, IndexError):return Nonestc LocalStack()stc.push(123) v stc.pop()print(v)object.__setattr__(self, storage, {}) self.storage {} 对象.xx def __setattr__(self, key, value):print(key,value)
http://www.dnsts.com.cn/news/159114.html

相关文章:

  • 环保h5微网站wordpress 导出附件
  • 建个简单网站唯品会官网一家做特卖的网站
  • 网站弄好了怎么推广帝国转wordpress程序
  • 专业网站快速wordpress编写模板
  • 怎么创建网站与网页免费网站素材下载
  • 百度云做网站空间已经有了网站源代码怎样搭建
  • 专题网站模板wordpress 菜价插件
  • 网站建设多少钱一个站网站 app
  • 网站导航面包屑做网站编辑有什么发展
  • 重庆豆花制作深圳网站优化平台
  • 千灯网站建设网络舆情监测 toom
  • 域名服务器没有该网站的域的列表查询网ip138子域名
  • 网站建设销售客户疑问外贸网店平台
  • 网站内部优化方法盐城seo
  • 做网站累吗商标注册网上查询
  • 公司的服务器能建设网站吗h5页面 个人网站
  • 中山网络推广公司三门峡网站优化
  • 网站开发有必要用php框架如何给网站做外链
  • 网站建设有哪三部南京网站建设招聘
  • 图片模板 网站源码微信设计网站建设
  • 怎么做网站登录站网站做数据分析
  • 设计网站做海报宁至网站建设
  • 深圳公司网站设计哪家好目前最牛的二级分销模式
  • 做淘宝头像的网站有哪些查询系统网站模板
  • 个人网站备案能做宣传用么网站开发主要学些什么软件
  • 一般网站开发公司不用下载劰网站的片你懂的
  • 网站运营方案书法制建设网站
  • wordpress搭建个人网站费用营销网站科技
  • 做网站如何给图片命名wordpress 禁止索引目录
  • 跨境电商建站工具智库网站建设方案