一、系统概要
本次作业参考了简书网站,为创作者提供创作和交流平台,布局简单明了,色调整体偏冷,为创作者提供干净的创作空间。
网站的设计与实现使用了Python+Flask+Mysql的web建设技术,实现了以下几个功能:
- 网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局
- 注册、登录、注销
- 发布、列表显示
- 详情页
- 评论、列表显示
- 个人中心
- 搜索,条件组合搜索
- 文章分类、显示
- 点赞、收藏
- 修改密码、头像、上传头像
- 我的发布、点赞、收藏、评论
- 高级搜索
- 热门文章、推荐文章
二、网站结构设计
(1)业务流程图
根据该项目的功能要求,得到的业务流程图所示:
(2)数据库表
考虑各个字段数据类型和数据之间的关系,可以得到用户表、发布表、评论表、收藏表、点赞表:
三、模块实现
以下1-5点是实现登录、注册、修改密码和头像等等各个功能的必要算法:
1、建立实现各模块的视图函数,之后在html文件中通过{{ url_for('') }}调用各函数,以此实现登录、查询、发布、修改密码和头像等功能。
2、通过request请求获取表单内容并传值。
3、通过filter函数过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
4、用if函数进行条件判断。
5、通过session进行会话连接,匹配成功,return下一步操作。
举个例子,登录操作中的视图函数如图所示:
# 登录
@app.route('/denglu/', methods=['GET', 'POST']) # methods定义两种请求方式
def denglu():
if request.method == 'GET':
return render_template('denglu.html')
else:
username = request.form.get('user') # post请求模式,安排对象接收数据
password = request.form.get('pass')
user = User.query.filter(User.username == username).first() # 作查询,并判断
if user: # 判断用户名
if user.check_password(password): # 判断密码
session['user'] = username
session['user_id'] = user.id
session.permanent = True # 设置永久有效
return redirect(url_for('daohang')) #重定向到首页
else:
return u'用户密码错误'
else:
return u'用户不存在,请先注册'
6、作为游客,想要实现发布帖子、评论、收藏、点赞等功能,需要先登录,定义一个登录装饰器,在游客点击发布评论等操作时跳转到登录页面:
def loginFirst(fabu): @wraps(fabu) def wrapper(*args, **kwargs): # 定义wrapper函数将其返回,用*args, **kwargs把原函数的参数进行传递 if session.get('user'): # 只有经过登陆,session才能记住并get到值 return fabu(*args, **kwargs) else: return redirect(url_for('denglu')) return wrapper
7、定义上下文处理器,定义变量然后在所有模板中都可以调用:
#上下文处理器
@app.context_processor def mycontext(): user = session.get('user') user_id = session.get('user_id') if user: return {'username': user, 'sessionuserid': user_id} else: return {}
8、在评论、收藏、点赞等操作时,需要定义一个参数,例如comment、dianzan、shoucang,这个参数包含了详情、发布者id和评论者id,将对象从表单中接受到的数据commit存到数据库中:
# 跳转评论。 @app.route('/comment/', methods=['POST']) @loginFirst def comment(): detail = request.form.get('pinglun') author_id = User.query.filter(User.username == session.get('user')).first().id fabu_id = request.form.get('fa_id') comment = Comment(detail=detail, author_id=author_id, fabu_id=fabu_id) db.session.add(comment) # 执行操作 db.session.commit() # 提交到数据库 return redirect(url_for('fabuview', fabu_id=fabu_id)) # 重定向到fabuview请求时要带fabu_id
9、在做用户个人中心时,定义了几个tag,将各个页面区分开,在执行不同的请求时跳到不同的页面:
# 跳转用户详情 @app.route('/yonghu/<username_id>/<tag>') def yonghu(username_id, tag): user = User.query.filter(User.id == username_id).first() shoucang = Shoucang.query.filter(Shoucang.author_id == username_id).all() context = { 'userid': user.id, 'username': user.username, 'nickname': user.nickname, 'fabus': user.fabu, 'comments': user.comments, 'shoucang': shoucang, 'user': username_id } if tag == '1': return render_template('usercenter1.html', **context) elif tag == '2': return render_template('usercenter2.html', **context) elif tag == '3': return render_template('usercenter3.html', **context) elif tag=='4': return render_template('usercenter4.html', **context) else: return render_template('password_update.html', **context)
10、在做模糊查找时可参考:
# 模糊查找 @app.route('/search') def search(): qu = request.args.get('q') c = '' if request.args.get('c') == '' else request.args.get('c') y = '' if request.args.get('y') == '' else request.args.get('y') query = Fabu.query.filter( or_( Fabu.title.contains(qu), Fabu.detail.contains(qu), ), Fabu.cf.like('%' + c + '%'), Fabu.creat_time.like('%' + y + '%'), ).order_by('-creat_time').all() context = { 'questions': query, 'cf': Cf.query.all(), } return render_template('daohang.html', **context)
11、在html文件中定义{% X in Y}可进行迭代排序:
{% for foo in fabus %} <tr> <td><a href="{{ url_for('fabuview',fabu_id=foo.id) }}">{{ foo.title }}</a></td> <td><span class=" "></span><em> <small>作者:{{ foo.author.username }}</small> </em></td> </tr> {% endfor %}
12、子模板继承父模板 {% extends 'base.html’ %}
- 父模板提前定义好子模板可以实现一些自己需求的位置及名称。
- <title>{% block title %}{% endblock %}-首页</title>
- {% block head %}{% endblock %}
- {% block main %}{% endblock %}
子模板中写代码实现自己的需求。 - {% block title %}登录{% endblock %}
{% extends 'daohang.html' %} {% block daohangtitle %}发布详情{% endblock %} {% block daohanghead %}{% endblock %} {% block daohangbody %}
四、成品展示
五、总结
python的学习已有一年,比刚开始的一无所知好多了,但依然任重道远,一步步来吧。flask框架是一个非常灵活的框架,希望继续深入学习。