Flask路由,相信大家都会了,官方文档快速入门说得很详细,但这不是本文讲的主题,今天跟大家谈谈如何让路由自动化。
也许大家对Flask的印象就是一个Path路径绑定一个方法,当一个项目有很多Path,绑定N个方法的时候,在一个py文件里堆积太多的方法,很难管理,这时我们希望可以把这些方法分散到多个py文件中,你是不是感觉不知从哪里下手,下面我来跟大家谈一下我的做法。
我们创建一个项目Test
在Test目录下创建一个目录viewcontrol目录,里面创建大量项目需要的视图控制器,比如我创建一个控制器 person.py, 我希望自动化路由可以自动遍历viewcontrol目录,读出所有控制器,并获得所有方法,基于路径来自动创建路由,是不是感觉很难懂,请原谅我的表达能力不好,还是举例吧。
person.py
class person():
def save(self):
return "save"
viewcontrol/person.py文件创建了一个类person,名称和文件名相同,这很重要,后面解释为什么要同名
下面我要创建一个自动化路由的类
import os
import importlib
import inspect
from stat import *
class Route():
def __init__(self,flask_app,DIR,appName):
self.__app = flask_app
self.__Dir = DIR
self.__appName = appName
self.viewControlDir = DIR+"/app/" + appName + "/viewcontrol/"
def build(self):
self.__make(self.viewControlDir)
def __make(self,top):
for f in os.listdir(top):
pathname = os.path.join(top, f)
try:
mode = os.stat(pathname).st_mode
except PermissionError:
continue
else:
if S_ISDIR(mode):
try:
self.__make(pathname)
except PermissionError:
continue
elif S_ISREG(mode):
self.url(pathname,f.replace(".py",""))
else:
pass
def url(self,pathname,name):
moduleStr = pathname.replace(self.__Dir+"/","").replace(".py","").replace("/",".")
moduleObj = importlib.import_module(moduleStr)
for classStr in dir(moduleObj):
if not classStr.startswith("__") and classStr.lower()==name.lower():
classObj = getattr(moduleObj, classStr)
# load= getattr(obj, "Load")
# inspect.getargspec(load) #获得方法参数
obj = classObj()
urlPath = pathname.replace(self.__Dir,"").replace("/app/"+self.__appName+"/viewcontrol","").replace(".py","").lower()
for methodName in dir(classObj):
if not methodName.startswith("__"):
self.__app.add_url_rule(urlPath+"/"+methodName.lower(), endpoint=urlPath.replace("/","-")+"-"+methodName, view_func=getattr(obj, methodName),methods=["GET","POST"])
大概思路是遍历viewcontrol目录,根据目录文件,自动生成路由,关键是 url方法,动态加载模块,动态获得类方法,最后通过 add_url_urle方法创建路由。
在入口程序中,调用
Route(application,Dir,"e2").build()
即可自动遍历viewcontrol目录的所有类方法,绑定一个对应的path路径,如person的save方法,好可绑定了路径 http://ip:port/person/save
这样我就可以根据业务在viewcontrol里创建不同的py文件,根据功能创建不同的方法,而不需要考虑增加一个功能需要在入口程序再手工增加对应方法这么麻烦了。