第十七天 实战练习(4)
今天计划用Python继续一个web开发的实战项目练习,学习项目及练习源码地址:
GitHub源码
补坑
多个装饰器
在处理session middware时遇到个奇怪的坑,经调试发现,aiohttp_session在处理时是在app handler上加了一个装饰器,和本来处理handler response的装饰器发生冲突。专门研究了多个装饰器的执行顺序问题。
def decorator_a(func):
print('Get in decorator_a')
def inner_a(*args,**kwargs):
print('Get in inner_a')
res = func(*args,**kwargs)
return res
return inner_a
def decorator_b(func):
print('Get in decorator_b')
def inner_b(*args,**kwargs):
print('Get in inner_b')
res = func(*args,**kwargs)
return res
return inner_b
@decorator_b
@decorator_a
def f(x):
print('Get in f')
return x * 2
f(1)
'''
Get in decorator_a
Get in decorator_b
Get in inner_b
Get in inner_a
Get in f
'''
从上面的输出,很容易首先是按装饰器的的装饰顺序内到外一次装入,执行的时候按装入的顺序执行,最后执行被装饰的函数。
所以,在实战中需要将session装饰器,放到response handler后面。
aiohttp_session.setup(app, storage)
app.middlewares.append(response_factory) #一定要放在session的后面,保证先执行这个
如果从使用的角度来看,装饰器其实是自顶向下的(毕竟实际使用过程中一般不会在外层打印信息)
意思就是说app.middlewares这个列表中定义的中间件,最先执行的是列表最后一个元素,然后依次序向上,这个在实际工作中一定要注意。
在servie层中定义is_login()装饰器
为了保持路由层的简洁,将一些常用的装饰放入service中,这个也是符合业务逻辑的。判断一个请求是否已经登录本身就是一个业务控制逻辑。
aiohttp_jinja2模块暂停使用
采用另一中方式来渲染模板,需要暂时停用aiohttp_jinja2。它内部提供的装饰器与现有装饰器有一定冲突。
统一处理返回response
async def response_factory(app, handler):
async def response(request):
logging.info('Response handler...')
r = await handler(request)
if isinstance(r, web.StreamResponse): # 这里期望是在handler处理之后继续进行处理,这个和之前的session有关系
return r
if isinstance(r, bytes):
# 最终返回到结果是经过一些列封装后的web.Response对象,在session中会继续处理这个对象
预处理请求的数据
async def data_factory(app, handler):
async def parse_data(request):
if request.method == 'POST':
if request.content_type.startswith('application/json'):
request.__data__ = await request.json()
logging.info('request json: %s' % str(request.__data__))
elif request.content_type.startswith('application/x-www-form-urlencoded'):
request.__data__ = await request.post()
logging.info('request form: %s' % str(request.__data__))
return (await handler(request))
# 注意和上面的response书写结构进行对比,此处的目的是预处理请求的参数,那么应该放在handler前面
综上,可以很好的理解多个装饰器以及app.middware该如何使用了
找一个合适的模板
打算用传统的bootstrap和jquery还实现期望的目的。
避开前后分离,注重于后端代码的学习
计划
下一次完成博客内容的添加
- 完善用户登录和未登录状态
- 需要实现用户在线通过富文本编辑博客内容。
- 展现文章列表和详情