管理信息系统 课程设计
操作说明:
- 系统概要说明
- 本课程设计很大的改进,学习了flask的新知识,更深入了解flask框架,Flask选择组件的额外工作给那些使用案例不适用标准ORM的开发者提供了更多的灵活性,同样也给使用不同工作流和模版化系统的开发者们带来了灵活性,虽然Flask历史相对更短,但它能够学习之前出现的框架并且把注意力放在了微小项目上。它大多数情况被使用在一些只有一两个功能的小型项目上。例如 httpbin,一个简单的(但很强大的)调试和测试HTTP库的项目。
- 最开始跟着视频学习的时候,感觉和上课老师讲的完全不一样,完全就是新的知识,完全是从头开始,我印象深刻的是虚拟环境的搭建,还有映射,数据库的连接和导入。这些步骤很大程度上一不小心就走错一步,整个程序就不成功了,我就在重新创建和不停删除虚拟环境中度过。virtualenv是一个工具,可以利用它创建与操作系统python环境相孤立的python运行环境,方便测试和开发依赖包的管理。
- 网站结构设计
- 网站结构和上学期大体上没有什么区别,大致改了很多细致的设计。网站结构主要大概有主页、登录注册页 、发布帖子、详情页和个人中心页。新添的模块都是在这些基础上,再次修改和完善,比如主页上的导航,搜索,热门推荐和分类,详情页里的点赞收藏按键,评论列表和推荐文章,个人中心页的更改信息和我的收藏等。
- 系统实现的关键算法与数据结构
- 系统的实现大概与上学期差不多,我大概展示新添的几个模块的功能,主py文件
- 修改密码
1 #修改密码 2 @app.route('/setPassword/<id>', methods=['GET', 'POST']) 3 @loginFirst 4 def setPassword(id): 5 if request.method == 'GET': 6 return render_template('setPassword.html') 7 else: 8 user = User.query.filter(User.id == id).first() 9 if user: 10 if user.check_password(request.form.get('old')): 11 user.password = request.form.get('new1') 12 db.session.commit() 13 info = '修改成功' 14 else: 15 info = '原密码错误' 16 else: 17 info = '未知错误' 18 return redirect(url_for('index', info=info))
- 上传头像
1 # 上传头像 2 @app.route('/uploadLogo/<user_id>', methods=['GET', 'POST']) 3 @loginFirst 4 def uploadLogo(user_id): 5 user = User.query.filter(User.id == user_id).first() 6 f = request.files['logo'] 7 basepath = os.path.dirname(__file__) # 当前文件所在路径 8 upload_path = os.path.join(basepath, 'static/uploads', f.filename) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径 9 f.save(upload_path) 10 user.icon = 'uploads/' + f.filename 11 db.session.commit() 12 return redirect(url_for('setPassword', id=user_id));
- 个人中心以及我的收藏
1 # 个人中心 2 @app.route('/comment/<user_id>/<num>') 3 @loginFirst 4 def comment(user_id, num): 5 user = User.query.filter(User.id == user_id).first() 6 content = { 7 'comment': user.comment, 8 'questions': user.question, 9 'user2': user, 10 } 11 if (num == '1'): 12 return render_template('subComment1.html', **content, title='全部问题') 13 elif (num == '2'): 14 return render_template('subComment2.html', **content) 15 elif (num == '3'): 16 return render_template('subComment3.html', **content) 17 elif (num == '4'): 18 content = { 19 'comment': user.comment, 20 'questions': user.collection.all(), 21 'user2': user, 22 } 23 return render_template('subComment1.html', **content, title='我的收藏') 24 else: 25 return render_template('subComment1.html', **content)
1 @app.route('/c/<cf>') 2 def c(cf): 3 content = { 4 'questions': Question.query.filter(Question.cf == cf).order_by('-creat_time').all(), 5 'cf': Cf.query.all(), 6 'hot': Question.query.order_by('-click').all()[0:5] 7 } 8 return render_template('index.html', **content)
- 详情页的点赞和收藏功能
1 # 详情页 2 @app.route('/detail/<question_id>', methods=['GET', 'POST']) 3 @loginFirst 4 def detail(question_id): 5 quest = Question.query.filter(Question.id == question_id).first() 6 u = User.query.filter(User.id == session.get('user_id')).first() 7 if request.method == 'POST': 8 if request.form.get('click') == '1': 9 quest.click = quest.click + 1 10 if request.form.get('collection') == '1': 11 user = u 12 user.collection.append(quest) 13 db.session.add(user) 14 col = u.collection.filter_by(id=question_id).first() 15 if col is None: 16 col = {} 17 comment = Comment.query.filter(Comment.question_id == question_id).order_by('-creat_time').all() 18 quest.look = quest.look + 1 19 content = { 20 'ques': quest, 21 'comment': comment, 22 'col': col, 23 'questions': Question.query.filter(Question.cf == quest.cf).all(), 24 } 25 db.session.commit() 26 return render_template('detail.html', **content)
- 高级查找
1 # 高级查找 2 @app.route('/search') 3 def search(): 4 qu = request.args.get('q') 5 c = '' if request.args.get('c') == '' else request.args.get('c') 6 y = '' if request.args.get('y') == '' else request.args.get('y') 7 query = Question.query.filter( 8 or_( 9 Question.title.contains(qu), 10 Question.detail.contains(qu), 11 ), 12 Question.cf.like('%' + c + '%'), 13 Question.creat_time.like('%' + y + '%'), 14 ).order_by('-creat_time').all() 15 context = { 16 'questions': query, 17 'cf': Cf.query.all(), 18 'hot': Question.query.order_by('-click').all()[0:5] 19 } 20 return render_template('index.html', **context)
- 数据库设计
- 数据库的设计,新添了两个表,分别是收藏表和分类栏目表,数据库的设计在虚拟环境里面,需要在虚拟环境里python manage.py db init,更新需要的库和更新你创的数据库模型,并把它导入进去,然后在数据库就能见到了新创的表了。
- 收藏表
1 # 收藏表 2 Collection = db.Table( 3 'collection', 4 db.Column('id', db.Integer, primary_key=True, autoincrement=True), 5 db.Column('book_id', db.Integer, db.ForeignKey('question.id')), # 评论对应的文章的id 6 db.Column('collection', db.Integer, db.ForeignKey('user.id')), # 收藏用户的id 7 db.Column('createdate', db.DATETIME) # 发布时间 8 )
- 分类表,需在后台手动添加数据
1 # 分类 2 class Cf(db.Model): 3 __tablname__ = 'cf' 4 id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 数据库唯识别id 5 name = db.Column(db.String(30)) # 文章名称 6 context = db.Column(db.TEXT) # 分类内容
- 模块详细设计
- 模块设计大概与上学期差不多,我大概展示新添的几个模块的功能,主html文件,都是在有母版的继承下展开的
- 更改信息(上传头像和修改密码的功能)
{% extends 'base.html' %} {% block title %} 修改信息 {% endblock %} {% block link %} {% endblock %} {% block box %} <div class="container" style="padding-top: 200px;"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column"> <div style="margin: 80px 0px;margin-left: 70px;"> <form class="form-horizontal" role="form" method="post" enctype="multipart/form-data" action="{{ url_for('uploadLogo',user_id=user_id) }}"> <div class="form-group"> <div class="col-sm-10"> <h1>上传头像</h1> <input type="file" id="exampleInputFile" name="logo" required> <button type="submit" class="btn btn-default">上传头像</button> <img src="{{ url_for('static',filename=user.icon) }}" width="100px"/> </div> </div> </form> </div> <hr> <form class="form-horizontal" role="form" method="post"> <div class="form-group" > <h1 style="margin-left: 70px;">修改密码</h1> <label for="inputEmail3" class="col-sm-2 control-label">原密码</label> <div class="col-sm-10"> <input type="password" name="old" class="form-control" id="p1" required/> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">新密码</label> <div class="col-sm-10"> <input type="password" name="new1" class="form-control" id="p2" required/> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">确定密码</label> <div class="col-sm-10"> <input type="password" class="form-control" id="p3" required/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default" onclick="return f()">提交</button> </div> </div> </form> </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %} {% block script %} <script> function f() { if ($('#p2').val() == $('#p3').val()) return true; alert('两次密码不一样'); return false; } </script> {% endblock %}
- 个人中心页(我的问答、评论、信息、收藏等)
{% extends 'base.html' %} {% block title %} 个人中心 {% endblock %} {% block link %} {% endblock %} {% block box %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column"> <ul class="nav nav-tabs"> <li role="presentation"><a href="{{ url_for('comment',user_id=user2.id,num='1') }}">全部问题</a></li> <li role="presentation"><a href="{{ url_for('comment',user_id=user2.id,num='2') }}">全部评论</a></li> <li role="presentation"><a href="{{ url_for('comment',user_id=user2.id,num='3') }}">个人信息</a></li> <li role="presentation"><a href="{{ url_for('comment',user_id=user2.id,num='4') }}">我的收藏</a></li> </ul> {% block subComment %}{% endblock %} </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %} {% block script %} {% endblock %}
{% extends 'comment.html' %} {% block subComment %} <ul class="list-group" style=""> <h1>{{ title }}</h1> {% for foo in questions %} <li class="list-group-item" style="width: 800px"> <a class="wrap-img" href="#" target="_blank"> <img src="{{ url_for('static',filename=foo.author.icon) }}" width="50px"> </a> <span class="glyphicon glyphicon-left" aria-hidden="true"></span> <a href="{{ url_for('comment',user_id=foo.author.id ,num='1')}}" target="_blank">{{ foo.author.username }}</a> <br> <a href="{{ url_for('detail',question_id=foo.id) }}">{{ foo.title }}</a> <span class="badge">{{ foo.creat_time }}</span> <p style="">{{ foo.detail[0:50] }}... </p> </li> {% endfor %} </ul> {% endblock %}
{% extends 'comment.html' %} {% block subComment %} <ul class="list-group" style="margin-top: 30px;"> <h1>全部评论</h1> {% for com in comment %} <li class="list-group-item" style="width: 800px"> <a class="wrap-img" href="#" target="_blank"> <img src="{{ url_for('static',filename=com.author.icon) }}" width="50px"> </a> <span class="glyphicon glyphicon-left" aria-hidden="true"></span> <a href="{{ url_for('comment',user_id=com.author.id,num='1') }}" target="_blank">{{ com.author.username }}</a> <br> <span class="badge">{{ com.creat_time }}</span> <p style="">{{ com.detail }}</p> </li> {% endfor %} </ul> {% endblock %}
{% extends 'comment.html' %} {% block subComment %} <div class="list-group-item" style="margin-top: 30px;width: 800px;"> <h1>头像: <img src="{{ url_for('static',filename=user2.icon) }}" width="100px"> </h1> <h1>名称: <small>{{ user2.username }}</small> </h1> <h1>问题数: <small>{{ questions|length }}</small> </h1> <h1>评论数: <small>{{ comment|length }}</small> </h1> </div> {% endblock %}
- 详情页(浏览数,点赞、收藏功能,评论展示功能。热门文章推荐功能)
{% extends 'base.html' %} {% block title %} 详情页 {% endblock %} {% block link %} <script src="{{ url_for('static',filename='ueditor/ueditor.config.js') }}"></script> <script src="{{ url_for('static',filename='ueditor/ueditor.all.min.js') }}"></script> {# <script src="{{ url_for('static',filename="front/js/front_pdetail.js") }}"></script>#} {% endblock %} {% block box %} <div class="container"> <div class="row clearfix"> <div class="col-md-2 column"> </div> <div class="col-md-8 column"> <h1>{{ ques.title }}</h1> <div style="padding: 10px;"> <span style="padding-left: 10px;">作者:{{ ques.author.username }}</span> <span style="padding-left: 10px;">浏览数:{{ ques.look }}</span> <span style="padding-left: 10px;">点赞数:{{ ques.click }}</span> <form method="post" style="display: inline-block;padding-left: 10px;"> <input name="click" value="1" type="hidden"> <button class="glyphicon glyphicon-heart">点赞</button> </form> <form method="post" style="display: inline-block;padding-left: 10px;"> <input name="collection" value="1" type="hidden"> {% if col %} <button type="button" disabled>已收藏</button> {% else %} <button class="glyphicon glyphicon-leaf">收藏</button> {% endif %} </form> </div> <div style="padding: 70px 20px;margin-bottom: 100px;border:1px solid #eee;"> {# <p>#} {# {{ ques.detail }}#} {##} {# </p>#} <article class="ques-detail" id="ques-detail" data-id="{{ ques.id }}"> {{ ques.detail |safe }} </article> </div> <hr> <div style="padding: 15px;"> <h1>推荐文章</h1><br> {% for foo in questions %} <li class="list-group-item" style="width: 700px"> <a class="wrap-img" href="#" target="_blank"> <img src="{{ url_for('static',filename=foo.author.icon) }}" width="50px"> </a> <span class="glyphicon glyphicon-user" aria-hidden="true"></span> <a href="{{ url_for('comment',user_id=foo.author.id ,num='1') }}" target="_blank">{{ foo.author.username }}</a> <br> <a href="{{ url_for('detail',question_id=foo.id) }}">{{ foo.title }}</a> <span class="badge">{{ foo.creat_time }}</span> <p style="">{{ foo.detail[0:50] }}... </p> </li> {% endfor %} </div> <hr> <form class="form-horizontal" role="form" method="post" action="{{ url_for('answer') }}"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">评论内容</label> <div class="col-sm-10"> <input type="text" name="author_id" value="{{ user.id }}" hidden> <input type="text" name="question_id" value="{{ ques.id }}" hidden> <script id="editor" type="text/plain" name="detail"></script> {# <textarea class="form-control" name="detail" rows="10"></textarea>#} </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default" id="comment-btn">发布</button> </div> </div> </form> <hr> <h1>用户评论</h1><br> <ul> {% for com in comment %} <li class="list-group-item"> <img src="{{ url_for('static',filename=com.author.icon) }}" width="50px"> {# <h4>{{ com.author.username }}</h4>#} <h4><a href="{{ url_for('comment',user_id=com.author.id ,num='1') }}" target="_blank">{{ com.author.username }}</a></h4> <span class="badge">{{ com.creat_time }}</span> <div> <p>{{ com.detail }}</p> </div> </li> {% endfor %} </ul> </div> <div class="col-md-2 column"> </div> </div> </div> {% endblock %} {% block script %} <script> $(function () { var ue = UE.getEditor("editor", { 'serverUrl': '../static/ueditor/upload/', "toolbars": [ [ 'undo', 'redo', 'bold', 'italic', 'source', 'blockquote', 'selectall', 'fontfamily', 'fontsize', 'simpleupload', 'emotion' ] ] }) window.ue = ue; }); </script> {% endblock %}
- 主页(导航里的高级搜索,按文字查找、分类查找、时间查找等)
<nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <img src="{{ url_for('static',filename='img/8-1306061335461b.jpg') }}" alt="" width="50px"> <a class="navbar-brand" href="{{ url_for('index') }}">广商论坛</a> </div> <div> <ul class="nav navbar-nav"> <li class="dropdown">{# active 可以显示为点亮 #} <a href="{{ url_for('index') }}" class="dropdown-toggle" data-toggle="dropdown"> 首页 <b class="caret"></b> </a> <ul class="dropdown-menu"> <li><a href="#">军事</a></li> <li><a href="#">体育</a></li> <li><a href="#">生活</a></li> <li class="divider"></li> </ul> </li> {% if user_id %} <li class="drop_down"> <a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown"> {{ user.username }} <b class="caret"></b> </a> <ul class="dropdown-menu"> <li><a href="{{ url_for('setPassword',id=user_id) }}">更改信息</a></li> <li><a href="{{ url_for('comment',user_id=user_id,num='1') }}">个人中心</a></li> <li class="divider"></li> <li><a href="{{ url_for('logout') }}">退出</a></li> </ul> </li> {% else %} <li class=""><a href="{{ url_for('login') }}">登录</a></li> <li><a href="{{ url_for('regist') }}">注册</a></li> {% endif %} <li class=""><a href="{{ url_for('question') }}">发布问答</a></li> <li class=""> <form class="navbar-form navbar-left" role="search" action="{{ url_for('search') }}" method="get"> <div class="form-group"> <input type="text" class="form-control" placeholder="搜索" required name="q"> </div> <div class="form-group"> <select class="form-control" name="c"> <option value="" selected>--分类--</option> {% for c in cf %} <option value="{{ c.id }}">{{ c.name }}</option> {% endfor %} </select> </div> <div class="form-group"> <select class="form-control" name="y"> <option value="" selected>--发布年份--</option> <option >2018</option> <option>2017</option> <option>2016</option> <option>2015</option> <option>2014</option> </select> </div> <button type="submit" class="btn btn-default">搜索</button> </form> </li> </ul> </div> </div> </nav>
- 成品展示
- 网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局
- 注册、登录、注销
- 发布、列表显示
- 详情页
- 评论、列表显示
- 个人中心
- 搜索,条件组合搜索
- 文章分类、显示
- 点赞、收藏
- 修改密码、头像、上传头像
- 我的发布、点赞、收藏、评论
- 高级搜索
- 热门文章、推荐文章
- 网站父模板统一布局:头部导航条、底部图片导航、中间主显示区域布局