2021-01-06 09:55发布
一、综述
基于兴趣尝试使用Python开发语言搭建一个基础的web框架,本次采用的方案是集成tornado方式。项目源码
二、开发环境
系统需要具备以下开发环境:
Python-3.7(Anaconda2020.02)tornado-6.0.3PyCharm开发工具
三、python下载tornado库
如果当前的环境里没有tornado依赖库,使用以下命令安装
pipinstalltornado
四、基于Python3.x搭建web框架
需具备上述开发环境后,方可进入以下搭建流程。推荐使用PyCharm开发工具,也可以使用其他的开发工具替代。
项目目录介绍
config.py:项目环境的基础配置文件application.py:自定义tornadoApplication启动类,自定义相关的配置等server.py:项目的启动类views:项目的路由定义及相关业务处理的目录,类似SpringBoot中的controllerstatic:该目录为项目的静态资源目录,用于存放js/css/img等静态资源templates:该目录为项目的模板页面资源文件,用于渲染相关的显示页面upfile:该目录为项目的文件上传基础目录
2.项目配置文件config.py
该文件统一管理项目的配置文件,包含启动的端口,tornado支持的一些web启动配置参数,项目的请求路由注册等。
importos
"""
#config
配置参数
options={
"port":8080
}
配置文件,相当于django里面的setting
配置application应用程序路由,即文件地址路径
BASE_DIRS=os.path.dirname(__file__)
当前file文件路径
##os.path.join(BASE_DIRS,"static")
拼接路径:如(BASE_DIRS/static),当然BASE_DIRS=当前文件的父类的文件路径
print("******config******")
print("BASE_DIRS",BASE_DIRS)
静态路由配置
STATIC_ROUTERS_CONFIGS={
"STATIC_PATH":os.path.join(BASE_DIRS,"static"),
"CSS_URL":os.path.join(BASE_DIRS,"static","css"),
"JS_URL":os.path.join(BASE_DIRS,"static","js"),
"IMG_URL":os.path.join(BASE_DIRS,"static","img")
tornado配置
settings={
"static_path":os.path.join(BASE_DIRS,"static"),#静态文件
#"static_url_prefix":"/static",
"template_path":os.path.join(BASE_DIRS,"templates"),#视图
"compiled_template_cache":True,
"autoescape":None,
"debug":True,
"cookie_secret":"OrGWKG+lTja4QD6jkt0YQJtk+yIUe0VTiy1KaGBIuks",
"xsrf_cookies":True,
"login_url":"/login"
3.项目自定义WebApplication
(1)创建MainApplication继承tornado.web.Application,自定义相关的静态资源路由配置。(2)**all_router_configs()**方法为抽取的views目录下定义的路由接口,这样可以按模块定义相应的路由和处理的Handler,下面会详细说到。
importtornado.web
importconfig
fromviewsimport*
fromconfigimportsettings
fromtornado.webimportStaticFileHandler,URLSpec
创建Application
classMainApplication(tornado.web.Application):
def__init__(self):
#BASEHANDLERS
handlers=[
#静态文件
URLSpec(r"/static/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["STATIC_PATH"]}),
URLSpec(r"/css/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["CSS_URL"]}),
URLSpec(r"/js/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["JS_URL"]}),
URLSpec(r"/img/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["IMG_URL"]}),
]
#SERVICEHANDLERS
handlers.extend(all_router_configs())
super().__init__(handlers=handlers,**settings)
print("******tornadowebapplicationconfigs******")
print("handlers",handlers)
print("setting",config.settings)
4.项目启动类server.py
项目的启动入库类server.py,启动命令:pythonserver.py
importtornado.ioloop
importtornado.httpserver
importtornado.options
importconfig#导入自定义配合的py文件
importapplication#导入自定义的应用程序模块
server服务配置
if__name__=="__main__":
app=application.MainApplication()
httpServer=tornado.httpserver.HTTPServer(app)
httpServer.bind(config.options["port"])
httpServer.start(1)
print("serversuccessstart,port:",config.options["port"])
tornado.ioloop.IOLoop.current().start()
5.views下路由定义介绍
views目录为项目所有的路由定义的地方及相关业务处理的模块,建议按业务模块化的方式管理。
5.1自定义路由接口ViewRouterInterface
接口统一定义获取注册路由方法,便于获取每个handler注册的路由配置。
统一定义路由配置URL
fromabcimportABCMeta,abstractmethod
定义公共的路由方法
classViewRouterInterface(metaclass=ABCMeta):
配置路由,要求返回数组行驶
@abstractmethod
defconfigRouter(self):
raiseNotImplementedError
5.2viewspackage默认的初始化文件__init__.py
(1)python中每当导入一个package时会默认先执行相关的__init__.py文件,可以借此时机获取项目里所有注册的handler。(2)ALL_HANDLERS为项目里注册的业务处理Handler,应为RequestHandler的子类(3)all_router_configs方法为views包下的全局方法,用于获取每个ALL_HANDLERS里配置的相关路由和请求处理器。
请求路由定义及相关的业务处理
Handler相当于Web中的Controller
ViewRouterInterface定义了获取路由配置的统一接口
即configRouter方法返回路由配置数组
print("******starttoimportviewRequestHandlerpackages******")
fromviews.test.TestHandlerKitimportTestHandler
fromviews.index.indeximportIndexHandler,LoginHandler
fromviews.upload.UploadUtilsHandlerKitimportUploadFileHandler
#定义所有的RequestHandler
ALL_HANDLERS=[
TestHandler,IndexHandler,LoginHandler,UploadFileHandler
获取所有的路由
defall_router_configs():
allRouters=[]
forviewRouterInterfaceinALL_HANDLERS:
routerConfigs=viewRouterInterface.configRouter(viewRouterInterface)
ifrouterConfigsisNone:
continue
allRouters.extend(routerConfigs)
print("ALLROUTERCONFIGS",allRouters)
returnallRouters
5.3自定义TestHandler
(1)按照模块化管理的思想,在views目录下创建test文件夹,创建TestHandler.py文件。(2)TestHandler继承ViewRouterInterface和RequestHandler类。(3)继承ViewRouterInterface是为了自定义相关的路由及处理Handler。(4)继承RequestHandler,实现其中的get和post方法用于处理Http的GET请求和POST请求,类似SpringBoot中的Controller。
fromtornado.webimportRequestHandler
fromviews.ViewRouterInterfaceimportViewRouterInterface
Testview
classTestHandler(ViewRouterInterface,RequestHandler):
#配置路由
return[
(r"/test",TestHandler)
#Get方法
defget(self):
items=["item1","item2","item3"]
items2=["item1","item2"]
defchecked(item):
return'checked=checked'ifiteminitems2else''
self.render("test/test.html",items=items,add=add,items2=items2,checked=checked)
HtmlPageFunction
defadd(x,y):
return(x+y)
5.4自定义test.html模板页面
(1)按照模板化管理的思想,建议模板页面同样使用模块化文件夹管理的方式,在templates目录下创建test目录。(2)创建test.html文件,简单demo显示Handler返回的结果及调用Handler里自定义的函数。
{%foriteminitems%}
{{checked(item)}}
/>{{item}}
{%end%}
addfunctest:2+2={{add(2,2)}}
一、综述
基于兴趣尝试使用Python开发语言搭建一个基础的web框架,本次采用的方案是集成tornado方式。项目源码
二、开发环境
系统需要具备以下开发环境:
Python-3.7(Anaconda2020.02)tornado-6.0.3PyCharm开发工具
三、python下载tornado库
如果当前的环境里没有tornado依赖库,使用以下命令安装
pipinstalltornado
四、基于Python3.x搭建web框架
需具备上述开发环境后,方可进入以下搭建流程。推荐使用PyCharm开发工具,也可以使用其他的开发工具替代。
项目目录介绍
config.py:项目环境的基础配置文件application.py:自定义tornadoApplication启动类,自定义相关的配置等server.py:项目的启动类views:项目的路由定义及相关业务处理的目录,类似SpringBoot中的controllerstatic:该目录为项目的静态资源目录,用于存放js/css/img等静态资源templates:该目录为项目的模板页面资源文件,用于渲染相关的显示页面upfile:该目录为项目的文件上传基础目录
2.项目配置文件config.py
该文件统一管理项目的配置文件,包含启动的端口,tornado支持的一些web启动配置参数,项目的请求路由注册等。
importos
"""
#config
配置参数
"""
options={
"port":8080
}
"""
#config
配置文件,相当于django里面的setting
配置application应用程序路由,即文件地址路径
BASE_DIRS=os.path.dirname(__file__)
当前file文件路径
##os.path.join(BASE_DIRS,"static")
拼接路径:如(BASE_DIRS/static),当然BASE_DIRS=当前文件的父类的文件路径
"""
BASE_DIRS=os.path.dirname(__file__)
print("******config******")
print("BASE_DIRS",BASE_DIRS)
"""
静态路由配置
"""
STATIC_ROUTERS_CONFIGS={
"STATIC_PATH":os.path.join(BASE_DIRS,"static"),
"CSS_URL":os.path.join(BASE_DIRS,"static","css"),
"JS_URL":os.path.join(BASE_DIRS,"static","js"),
"IMG_URL":os.path.join(BASE_DIRS,"static","img")
}
"""
tornado配置
"""
settings={
"static_path":os.path.join(BASE_DIRS,"static"),#静态文件
#"static_url_prefix":"/static",
"template_path":os.path.join(BASE_DIRS,"templates"),#视图
"compiled_template_cache":True,
"autoescape":None,
"debug":True,
"cookie_secret":"OrGWKG+lTja4QD6jkt0YQJtk+yIUe0VTiy1KaGBIuks",
"xsrf_cookies":True,
"login_url":"/login"
}
3.项目自定义WebApplication
(1)创建MainApplication继承tornado.web.Application,自定义相关的静态资源路由配置。(2)**all_router_configs()**方法为抽取的views目录下定义的路由接口,这样可以按模块定义相应的路由和处理的Handler,下面会详细说到。
importtornado.web
importos
importconfig
fromviewsimport*
fromconfigimportsettings
fromtornado.webimportStaticFileHandler,URLSpec
"""
创建Application
"""
classMainApplication(tornado.web.Application):
def__init__(self):
#BASEHANDLERS
handlers=[
#静态文件
URLSpec(r"/static/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["STATIC_PATH"]}),
URLSpec(r"/css/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["CSS_URL"]}),
URLSpec(r"/js/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["JS_URL"]}),
URLSpec(r"/img/(.*)",StaticFileHandler,{"path":config.STATIC_ROUTERS_CONFIGS["IMG_URL"]}),
]
#SERVICEHANDLERS
handlers.extend(all_router_configs())
super().__init__(handlers=handlers,**settings)
print("******tornadowebapplicationconfigs******")
print("handlers",handlers)
print("setting",config.settings)
4.项目启动类server.py
项目的启动入库类server.py,启动命令:pythonserver.py
importtornado.web
importtornado.ioloop
importtornado.httpserver
importtornado.options
importconfig#导入自定义配合的py文件
importapplication#导入自定义的应用程序模块
"""
server服务配置
"""
if__name__=="__main__":
app=application.MainApplication()
httpServer=tornado.httpserver.HTTPServer(app)
httpServer.bind(config.options["port"])
httpServer.start(1)
print("serversuccessstart,port:",config.options["port"])
tornado.ioloop.IOLoop.current().start()
5.views下路由定义介绍
views目录为项目所有的路由定义的地方及相关业务处理的模块,建议按业务模块化的方式管理。
5.1自定义路由接口ViewRouterInterface
接口统一定义获取注册路由方法,便于获取每个handler注册的路由配置。
"""
统一定义路由配置URL
"""
fromabcimportABCMeta,abstractmethod
"""
定义公共的路由方法
"""
classViewRouterInterface(metaclass=ABCMeta):
"""
配置路由,要求返回数组行驶
"""
@abstractmethod
defconfigRouter(self):
raiseNotImplementedError
5.2viewspackage默认的初始化文件__init__.py
(1)python中每当导入一个package时会默认先执行相关的__init__.py文件,可以借此时机获取项目里所有注册的handler。(2)ALL_HANDLERS为项目里注册的业务处理Handler,应为RequestHandler的子类(3)all_router_configs方法为views包下的全局方法,用于获取每个ALL_HANDLERS里配置的相关路由和请求处理器。
"""
请求路由定义及相关的业务处理
Handler相当于Web中的Controller
ViewRouterInterface定义了获取路由配置的统一接口
即configRouter方法返回路由配置数组
"""
print("******starttoimportviewRequestHandlerpackages******")
fromviews.test.TestHandlerKitimportTestHandler
fromviews.index.indeximportIndexHandler,LoginHandler
fromviews.upload.UploadUtilsHandlerKitimportUploadFileHandler
#定义所有的RequestHandler
ALL_HANDLERS=[
TestHandler,IndexHandler,LoginHandler,UploadFileHandler
]
"""
获取所有的路由
"""
defall_router_configs():
allRouters=[]
forviewRouterInterfaceinALL_HANDLERS:
routerConfigs=viewRouterInterface.configRouter(viewRouterInterface)
ifrouterConfigsisNone:
continue
allRouters.extend(routerConfigs)
print("ALLROUTERCONFIGS",allRouters)
returnallRouters
5.3自定义TestHandler
(1)按照模块化管理的思想,在views目录下创建test文件夹,创建TestHandler.py文件。(2)TestHandler继承ViewRouterInterface和RequestHandler类。(3)继承ViewRouterInterface是为了自定义相关的路由及处理Handler。(4)继承RequestHandler,实现其中的get和post方法用于处理Http的GET请求和POST请求,类似SpringBoot中的Controller。
fromtornado.webimportRequestHandler
fromviews.ViewRouterInterfaceimportViewRouterInterface
"""
Testview
"""
classTestHandler(ViewRouterInterface,RequestHandler):
#配置路由
defconfigRouter(self):
return[
(r"/test",TestHandler)
]
#Get方法
defget(self):
items=["item1","item2","item3"]
items2=["item1","item2"]
defchecked(item):
return'checked=checked'ifiteminitems2else''
self.render("test/test.html",items=items,add=add,items2=items2,checked=checked)
"""
HtmlPageFunction
"""
defadd(x,y):
return(x+y)
5.4自定义test.html模板页面
(1)按照模板化管理的思想,建议模板页面同样使用模块化文件夹管理的方式,在templates目录下创建test目录。(2)创建test.html文件,简单demo显示Handler返回的结果及调用Handler里自定义的函数。
{%foriteminitems%}
{{checked(item)}}
/>{{item}}
{%end%}
addfunctest:2+2={{add(2,2)}}