第十九天 实战练习(6)
今天计划用Python继续一个web开发的实战项目练习,学习项目及练习源码地址:
GitHub源码
处理用户登录session
在response中间件中加入处理用户登录的session,这样可以方便的传入用户登录的相关信息到模板渲染。
session = await get_session(request)
uid = session.get("uid")
r['is_login'] = False if not uid else True
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 is_login %}
<li class="nav-item">
<a class="nav-link" href="javascript:void(0);" id="u_logout">登出</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/b/write">写文章</a>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="/u/login">登录</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/u/register">注册</a>
</li>
{% endif %}
文章的保存和更新
@post('/b/{id}')
async def save_content(*,id,title,content,request):
if not title or not title.strip():
raise APIValueError('title')
if not content or not content.strip():
raise APIValueError('content')
session = await get_session(request)
uid = session.get('uid')
if not uid:
return {'success':False,'msg':'please login.'}
if id == '0':
blog = Blog(
user_id = uid,
user_name = '',
user_image = '',
name = title,
summary = '',
content = content
)
await blog.save()
return {'success':True,'blog_id':blog.id}
else:
blogs = await Blog.findAll('id=?', [id])
if len(blogs) != 1:
raise APIError('update:failed', 'id', 'id is not find.')
blog = blogs[0]
blog.name = title
blog.content = content
await blog.update()
return {'success':True,'blog_id':blog.id}
在这里只是简单的验证用户是否登录,实际中,应该防止用户通过非法手段狂写入文章数据。
文章列表的获取和展现
@get('/')
async def index(request):
blogs = await Blog.findAll(limit=5)
return {
'__template__':'index.html',
'blogs': blogs
}
前端渲染
{% for blog in blogs %}
<div class="ll-card">
<div class="row">
<div class="col-lg-2 col-md-3 col-sm-12 ll-card-image">
<a href="#">
<img src="/static/img/list-image.jpg" class="img-fluid" alt="Responsive image">
</a>
</div>
<div class="col-lg-10 col-md-9 col-sm-12 ll-card-main">
<h3 class="ll-card-main-title"><a href="/a/{{blog.id}}">{{ blog.name }}</a></h3>
<div class="ll-card-tag">
<div><i class="fa fa-clock-o"></i> 2017-10-01 18:00</div>
<div><i class="fa fa-eye"></i> 156</div>
<div><i class="fa fa-commenting-o"></i> 2</div>
</div>
<p class="ll-card-main-info">{{ blog.sumary }}</p>
<p class="ll-card-more"><a href="/a/{{blog.id}}">阅读更多...</a></p>
</div>
</div>
</div>
{% endfor %}
文章详情
@get('/a/{id}')
async def detail(id,request):
blogs = await Blog.findAll('id=?', [id],limit=1)
return {
'__template__':'detail.html',
'blog': blogs[0]
}
前端展现
<h2 class="ll-artical-title">{{blog.name}}</h2>
<div class="ll-card-tag">
<div class="">
<img src="img/list-image.jpg" class="img-fluid rounded-circle" alt="Responsive image">
<span class="text-success">海哥</span>
</div>
<div><i class="fa fa-clock-o"></i> 2017-10-01 18:00</div>
<div><i class="fa fa-eye"></i> 156</div>
<div><i class="fa fa-commenting-o"></i> 2</div>
</div>
<div class="ll-artical">
{{blog.content | safe}}
</div>
一个小坑: 要展现保存的富文本内容,需要要{{blog.content | safe}}
自此,文章的增,删,查,改已经全部完成,需要丰富文章的内容,如:查看次数,作者信息,文章配图显示等。
如何将张贴到富文本内容的图片连接转存到本地,过滤粘贴内容的外部连接等,是需要慢慢完成的工作。
网友评论