tornado项目搭建_Tornado Web 开发 框架搭建 (1)

环境配置

使用 python 3.3 和tornado, 其实也是个人兴趣问题,然后数据库也使用mysql, 这里 使用oracle 自家的 mysql-connector. 自然,orm就选择 sqlalchemy了. 模板引擎使用jinja2, form验证考虑wtforms。

879ec7c1126c240a4c2b57f942730600.png

项目配置大概如上。之后可能使用全文检索和数据库逐步更新功能,因此又附加了 alembic 和 whoosh 俩个包。

入口

先看下 入口 server.py

#coding=utf-8

import tornado.ioloop

from tornado.options import define, options

from lib.base import MainApplication

from lib.routes import make_handlers, include

from settings import URL_PREFIX

# Options

#define("port", default=8888, help="run on the given port", type=int)

#define("db_path", default='sqlite:tmp/test.db', type=str)

settings = {

"template_path": "template",

"static_path": "static",

"debug": True,

#"logging": "debug",

"login_url": '/login',

"cookie_secret": "61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",

"xsrf_cookies": True,

}

#application = MainApplication([#tornado.web.Application([

# (r"/", MainHandler),

#],**settings)

application = MainApplication(make_handlers(URL_PREFIX,

(r'/', include('handlers.index')),

(r'/', include('handlers.user')),

(r'/', include('handlers.userGroup')),

), **settings)

if __name__ == "__main__":

application.listen(8888)

tornado.options.options.logging = "debug"

tornado.options.parse_command_line()

tornado.ioloop.IOLoop.instance().start()

ROUTE

为了给tornado 实现 每个handler 单独配置url,

类似这样

@route('login/', name='login')

class LoginHandler(BaseHandler):

@tornado.web.asynchronous

def get(self):

self.render("login.html") 这里自己建了一个routes.py 参考

https://github.com/troolee/tornado-routes

#coding=utf-8

from pprint import pformat

import re

import logging

from tornado import web

from tornado.web import URLSpec

logger = logging.getLogger(__name__)

__ALL__ = ('make_handlers', 'include', 'route', 'routes', )

def handler_repr(cls):

return re.search("'(.+)'", repr(cls)).groups()[0]

class HandlersList(object):

def __init__(self, prefix, items):

self.prefix = prefix

self.items = items

def get_handler_name(self, handler, r):

name = getattr(handler, 'url_name', None)

if name:

return name

if hasattr(handler, 'get_url_name'):

name = handler.get_url_name(*r)

if name:

return name

if len(r) == 3 and 'url_name' in r[2]:

name = r[2].pop('url_name')

if name:

return name

return handler_repr(handler)

def build(self, prefix=None):

prefix = prefix or self.prefix or ''

res = []

for r in self.items:

print(r)

route = '/' + '/'.join([prefix.strip('/')] + r[0].strip('/').split('/')).strip('/')

print(route)

if isinstance(r[1], HandlersList):

res += r[1].build(route)

elif isinstance(r[1], str):

m = r[1].split('.')

ms, m, h = '.'.join(m[:-1]), m[-2], m[-1]

m = __import__(ms, fromlist=[m], level=0)

handler = getattr(m, h)[0]

d = {'name': self.get_handler_name(handler, r)}

#d.update(r[2:])

d['kwargs'] = {}

if len(r) == 3:

d['kwargs'] = r[2]

res.append(URLSpec(route, handler, **d))

if len(route) > 1:

#d['kwargs']['url'] = route;

d.pop('name')

res.append(URLSpec(route + '/', handler, **d))

else:

handler = r[1:][0]

d = {'name': self.get_handler_name(handler, r)}

d['kwargs'] = {}

if len(r) == 3:

d['kwargs'] = r[2]

res.append(URLSpec(route, handler, **d))

if len(route) > 1:

#d['kwargs']['url'] = route;

d.pop('name')

res.append(URLSpec(route + '/', handler, **d))

return res

def make_handlers(prefix, *args):

res = tuple(HandlersList(prefix, args).build())

rr = [(x.regex.pattern, x.handler_class, x.kwargs, x.name) for x in res]

logger.debug('\n' + pformat(sorted(rr, key=lambda a: a[0]), width=200))

return res

def include(module):

def load_module(m):

m = m.split('.')

ms, m = '.'.join(m), m[-1]

m = __import__(ms, fromlist=[m], level=0)

return m

if isinstance(module, (str,)):

module = load_module(module)

routes = []

for member in dir(module):

member = getattr(module, member)

if isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'routes'):

i = 1

for route_path, route_params in member.routes:

route_path.strip('/')

if not route_params:

route_params = {}

if 'url_name' not in route_params:

route_params['url_name'] = '%s~%d' % (handler_repr(member), i)

routes.append((route_path, member, route_params))

i += 1

elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'route_path'):

route_path, route_params = member.route_path, member.route_params

route_path.strip('/')

if route_params:

routes.append((route_path, member, route_params))

else:

routes.append((route_path, member))

elif isinstance(member, type) and issubclass(member, web.RequestHandler) and hasattr(member, 'rest_route_path'):

route_path, route_params = member.rest_route_path, member.route_params

route_path.strip('/')

if route_params:

routes.append((route_path, member, route_params))

routes.append((route_path + r'/([0-9]+)', member, route_params))

else:

routes.append((route_path, member))

routes.append((route_path + r'/([0-9]+)', member))

return HandlersList(None, routes)

route_classes = {}

def route(path, params=None, name=None):

params = params or {}

def decorator(cls):

if repr(cls) in route_classes:

raise Exception('Cannot bind route "%s" to %s. It already has route to "%s".' %

(path, cls, route_classes[repr(cls)]))

route_classes[repr(cls)] = path

cls.route_path = path

cls.route_params = params

url_name = params.pop('url_name', name)

cls.url_name = url_name

return cls

return decorator

def routes(*routes):

def decorator(cls):

cls.routes = routes

return cls

return decorator

同时支持url后缀带斜杠和不带斜杠的处理

配置好的route 还可以这样用

Login

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值