Python中Web框架編寫學習心得
阿新 • • 發佈:2018-08-25
記錄日誌 實例 心得 ret NPU oba esp ascii edi
作者:糊君
鏈接:https://www.jianshu.com/p/0fded26001e3
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。
學習廖雪峰老師的Python實戰教程,在Web框架這部分看了大致一個多禮拜,前面的知識學的不夠紮實,由於比較復雜,因此在這裏總結下,也算是鞏固了。
先看下框架的調用代碼:
app = web.Application(loop=loop, middlewares=[logger_factory, response_factory])
init_jinja2(app, filters=dict(datetime=datetime_filter))
add_routes(app, ‘handlers‘)
add_static(app)
- 使用web.Application類創建aiohttp server——app,其中loop為Eventloop用來處理HTTP請求,middlewares為中間件,在這裏用來記錄日誌並處理handler返回的數據為web.response對象,這裏看下
response_factory
async def response_factory(app, handler):
async def response(request):
logging.info(‘Response handler...‘)
#獲取handler的返回值,根據返回值的不同類型進行處理
r = await handler(request)
print(type(r))
if isinstance(r, web.StreamResponse):
return r
if isinstance(r, bytes):
resp = web.Response(body=r)
resp.content_type = ‘application/octet-stream‘
return resp
if isinstance(r, str):
if r.startswith(‘redirect:‘):
return web.HTTPFound(r[9:])
resp = web.Response(body=r.encode(‘utf-8‘))
resp.content_type = ‘text/html;charset=utf-8‘
return resp
if isinstance(r, dict):
template = r.get(‘__template__‘)
if template is None:
resp = web.Response(body=json.dumps(r, ensure_ascii=False, default=lambda o: o.__dict__).encode(‘utf-8‘))
resp.content_type = ‘application/json;charset=utf-8‘
return resp
else:
resp = web.Response(body=app[‘__templating__‘].get_template(template).render(**r).encode(‘utf-8‘))
resp.content_type = ‘text/html;charset=utf-8‘
return resp
if isinstance(r, int) and r >= 100 and r < 600:
return web.Response(r)
if isinstance(r, tuple) and len(r) == 2:
t, m = r
if isinstance(t, int) and t >= 100 and t < 600:
return web.Response(t, str(m))
# default:
resp = web.Response(body=str(r).encode(‘utf-8‘))
resp.content_type = ‘text/plain;charset=utf-8‘
return resp
return response
- 使用jinjia2模板來構建前端頁面,這裏我們暫時沒有用到
- 註冊處理url的handler,aiohttp中的add_route函數進行註冊,我們這裏使用
add_routes
對‘handlers‘模塊的handler進行批量註冊
def add_route(app, fn):
method = getattr(fn, ‘__method__‘, None)
path = getattr(fn, ‘__route__‘, None)
if path is None or method is None:
raise ValueError(‘@get or @post not defined in %s.‘ % str(fn))
if not asyncio.iscoroutinefunction(fn) and not inspect.isgeneratorfunction(fn):
fn = asyncio.coroutine(fn)
logging.info(‘add route %s %s => %s(%s)‘ % (method, path, fn.__name__, ‘, ‘.join(inspect.signature(fn).parameters.keys())))
app.router.add_route(method, path, RequestHandler(app, fn))
def add_routes(app, module_name):
#找到‘.‘則返回其所在位置,否則返回-1
n = module_name.rfind(‘.‘)
if n == (-1):
#mod為包含module_name模塊中全部屬性和方法的list
mod = __import__(module_name, globals(), locals())
else:
name = module_name[n+1:]
mod = getattr(__import__(module_name[:n], globals(), locals(), [name]), name)
for attr in dir(mod):
#檢查handler是否被@get或@post裝飾
if attr.startswith(‘_‘):
continue
fn = getattr(mod, attr)
if callable(fn):
method = getattr(fn, ‘__method__‘, None)
path = getattr(fn, ‘__route__‘, None)
if method and path:
add_route(app, fn)
這裏出現了一個RequestHandler類,它具有call魔術方法,所以可以像調用函數一樣調用其實例,這裏RequestHandler類主要是對handler進行封裝,獲取request中傳入的參數並傳入handler中。
- add_static是用戶處理如圖片、js、css等靜態資源的,僅供開發環境中方便使用,生產環境一般使用nginx或CDN之類的,這塊我也還沒有搞清楚,沒辦法梳理
最後把我的handler模塊的代碼貼出來,供參考:
from coroweb import get, post
from aiohttp import web
@get(‘/blog‘)
async def handler_url_blog(request):
body=‘<h1>Awesome: /blog</h1>‘
return body
@get(‘/greeting‘)
async def handler_url_greeting(*,name,request):
body=‘<h1>Awesome: /greeting %s</h1>‘%name
return body
@get(‘/input‘)
async def handler_url_input(request):
body=‘<form action="/result" method="post">E-mail: <input type="email" name="user_email" /><input type="submit" /></form>‘
return body
@post(‘/result‘)
async def handler_url_result(*,user_email,request):
body=‘<h1>您輸入的郵箱是%s</h1>‘%user_email
return body
@get(‘/index‘)
async def handler_url_index(request):
body=‘<h1>Awesome: /index</h1>‘
return body
@get(‘/create_comment‘)
async def handler_url_create_comment(request):
body=‘<h1>Awesome: /create_comment</h1>‘
return body
作者:糊君
鏈接:https://www.jianshu.com/p/0fded26001e3
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。
Python中Web框架編寫學習心得