管理信息系统 课程设计
一、系统概要说明
这个系统是一个动漫小论坛,一些动漫爱好者可以在此系统上讨论分析相关爱好的动漫,与漫友们一起讨论或者吐槽看动漫一大乐趣。进入到系统首页后,通过注册和登录用户名,即可以在小论坛上发布自己的槽点,与其他用户的互动可以有搜索,评论,点赞,收藏等。
二、网站结构设计
三、模块详细设计
1、首页
首页是作为父模板,内容主要有导航栏,在更新其他页面的时候,导航栏保持不变。导航栏包括:首页,发布信息,搜索栏,登录,注册等。
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title> 6 {%block title %}{% endblock %} 7 8 首页</title> 9 <link rel="stylesheet" type="text/css" href="../static/css/base.css"> 10 <script src="../static/js/base.js"></script> 11 <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> 12 <script src="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"></script> 13 14 {% block head %} 15 {% endblock %} 16 </head> 17 <body class="backgroud" id="myBody"> 18 19 20 <nav class="navbar navbar-default " role="navigation"> 21 <div class="container-fluid"> 22 <div class="navbar-header"> 23 <a class="navbar-brand" href="{{ url_for('index')}}">首页</a> 24 <a class="navbar-brand" href="{{ url_for('question') }}">发布问答</a> 25 <form action="{{ url_for('search') }}" method="get" class="navbar-form navbar-left"> 26 <input name="q" type="text" class="form-control" placeholder="请输入关键字"> 27 <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-search" aria-hidden="true"></span>查找</button> 28 </form> 29 </div> 30 <ul class="nav navbar-nav navbar-right"> 31 {% if username %} 32 <li><a href="{{ url_for('usercenter',user_id=session.get('userid'),tag=1) }}"><span class="glyphicon glyphicon-user"></span>{{ session.get('user') }}</a></li> 33 <li><a href="{{ url_for('logout')}}"><span class="glyphicon glyphicon-repeat"></span>注销</a></li> 34 {% else %} 35 <li><a href="{{ url_for('login')}}"><span class="glyphicon glyphicon-log-in"></span> 登录</a></li> 36 <li><a href="{{ url_for('register')}}"><span class="glyphicon glyphicon-user"></span> 注册</a></li> 37 {% endif %} 38 </ul> 39 </div> 40 41 </nav> 42 43 </body> 44 {% block main %} 45 46 <h2>ONE PIECE</h2> 47 48 <nav> 49 <img id="myOnOff" onclick="mySwitch()" 50 src="http://cdn5.lizhi.fm/audio_cover/2016/05/11/28444058722652679_320x320.jpg" width="30px"> 51 <script> 52 document.write(Date()) 53 </script> 54 </nav> 55 56 <div class="area"></div> 57 58 <div class="haizeiwang"> 59 <div class="img"> 60 <a href="https://tieba.baidu.com/p/5428362063? 61 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 62 src="https://imgsa.baidu.com/forum/w 63 %3D580/sign=b18fc3697dc6a7efb926a82ecdfbafe9/e5f5bc3eb13533fad415f598a3d3fd1f40345b96.jpg" 64 ></a> 65 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 66 lp=home_main_thread_pb&mo_device=1&pn=0&">路飞</a></div> 67 </div> 68 69 <div class="img"> 70 <a href="https://tieba.baidu.com/p/5428362063? 71 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 72 src="https://imgsa.baidu.com/forum/w 73 %3D580/sign=91526eaf26f5e0feee1889096c6134e5/69e7d1c8a786c9171e73338fc23d70cf3ac757c5.jpg" 74 ></a> 75 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 76 lp=home_main_thread_pb&mo_device=1&pn=0&">艾斯</a></div> 77 </div> 78 79 <div class="img"> 80 <a href="https://tieba.baidu.com/p/5428362063? 81 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 82 src="https://imgsa.baidu.com/forum/w 83 %3D580/sign=95cda2859a8fa0ec7fc764051696594a/2b076059252dd42adf29611d083b5bb5c9eab816.jpg" 84 ></a> 85 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 86 lp=home_main_thread_pb&mo_device=1&pn=0&">罗</a></div> 87 </div> 88 89 <div class="img"> 90 <a href="https://tieba.baidu.com/p/5428362063? 91 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 92 src="https://imgsa.baidu.com/forum/w 93 %3D580/sign=f9d9f398a3d3fd1f3609a232004f25ce/2e360ef41bd5ad6ea696045c8acb39dbb7fd3cc2.jpg" 94 ></a> 95 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 96 lp=home_main_thread_pb&mo_device=1&pn=0&">罗宾</a></div> 97 </div> 98 99 <div class="img"> 100 <a href="https://tieba.baidu.com/p/5428362063? 101 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 102 src="https://imgsa.baidu.com/forum/w 103 %3D580/sign=b9dda2b0a4c379317d688621dbc5b784/d4151f30e924b899682c198e65061d950a7bf626.jpg" 104 ></a> 105 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 106 lp=home_main_thread_pb&mo_device=1&pn=0&">萨博</a></div> 107 </div> 108 109 <div class="img"> 110 <a href="https://tieba.baidu.com/p/5428362063? 111 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 112 src="https://imgsa.baidu.com/forum/w 113 %3D580/sign=2e625a35042442a7ae0efdade142ad95/c53fb31bb051f819362b63fcd1b44aed2e73e72c.jpg" 114 ></a> 115 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 116 lp=home_main_thread_pb&mo_device=1&pn=0&">明哥</a></div> 117 </div> 118 119 <div class="img"> 120 <a href="https://tieba.baidu.com/p/5428362063? 121 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 122 src="https://imgsa.baidu.com/forum/w 123 %3D580/sign=f3d6d74d32dbb6fd255be52e3925aba6/4f34ebc4b74543a9202a997a15178a82b9011404.jpg" 124 ></a> 125 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 126 lp=home_main_thread_pb&mo_device=1&pn=0&">香吉</a></div> 127 </div> 128 129 <div class="img"> 130 <a href="https://tieba.baidu.com/p/5428362063? 131 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 132 src="https://imgsa.baidu.com/forum/w 133 %3D580/sign=22df6f5dbdfd5266a72b3c1c9b199799/17e9b74543a982266ce848918182b9014a90eb0d.jpg" 134 ></a> 135 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 136 lp=home_main_thread_pb&mo_device=1&pn=0&">娜美</a></div> 137 </div> 138 139 <div class="img"> 140 <a href="https://tieba.baidu.com/p/5428362063? 141 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 142 src="https://imgsa.baidu.com/forum/w 143 %3D580/sign=f560a558bf8f8c54e3d3c5270a282dee/01324134970a304e7f2ec34cdac8a786c9175c21.jpg" 144 ></a> 145 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 146 lp=home_main_thread_pb&mo_device=1&pn=0&">乔巴</a></div> 147 </div> 148 149 <div class="img"> 150 <a href="https://tieba.baidu.com/p/5428362063? 151 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 152 src="https://imgsa.baidu.com/forum/w 153 %3D580/sign=e06e8d3241ed2e73fce98624b700a16d/f4d7513d269759eeeb79027db9fb43166d22df0d.jpg" 154 ></a> 155 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 156 lp=home_main_thread_pb&mo_device=1&pn=0&">索隆</a></div> 157 </div> 158 159 <div class="img"> 160 <a href="https://tieba.baidu.com/p/5428362063? 161 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 162 src="https://imgsa.baidu.com/forum/w 163 %3D580/sign=1e086057242eb938ec6d7afae56385fe/aa639258d109b3ded66d87dec7bf6c81810a4c67.jpg" 164 ></a> 165 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 166 lp=home_main_thread_pb&mo_device=1&pn=0&">红发</a></div> 167 </div> 168 169 <div class="img"> 170 <a href="https://tieba.baidu.com/p/5428362063? 171 lp=home_main_thread_pb&mo_device=1&pn=0&"><img 172 src="https://imgsa.baidu.com/forum/w 173 %3D580/sign=6590facdda1373f0f53f6f97940e4b8b/26994aed2e738bd407cfd087aa8b87d6267ff94c.jpg" 174 ></a> 175 <div class="desc"><a href="https://tieba.baidu.com/p/5428362063? 176 lp=home_main_thread_pb&mo_device=1&pn=0&">汉库克</a></div> 177 </div> 178 </div> 179 180 181 {% endblock %} 182 </body> 183 184 </html>
2、注册、登录
在发布信息需要用户的注册和登录,如用户为登录,进入发布信息页面则会跳转登录页面。
登录:
<h2 >登录</h2> <form action="{{url_for('login') }}" method="post"> <div class="input_box" > 账户:<input id="uname" type="text" placeholder="请输入用户名" name="username"> </div> <div class="input_box"> 密码:<input id="upass" type="password" placeholder="请输入密码" name="password"> </div> <div id="error_box"><br></div> <div class="input_box"> <button onclick="fnLogin()">登录</button>
</div>
注册:
<h2>注册</h2> <form action="{{url_for('register') }}" method="post"> <div class="input_box"> <div class="col-sm-10"> 请输入账号:<input labid="uname" type="text" placeholder="请输入用户名" name="username"> </div> </div> <div class="col-sm-10"> 请输入昵称:<input id="nickname" type="text" placeholder="请输入昵称" name="nickname"> </div> <div class="input_box"> <div class="col-sm-10"> 请输入密码:<input id="upass" type="password" placeholder="请输入密码" name="password"> </div> </div> <div class="input_box"> <div class="col-sm-10"> 请确认密码:<input id="upass1" type="password" placeholder="再输入密码"> </div><br> </div> <div id="error_box"> </div><br> <div class="input_box"> <button onclick="fnLogin()" >注册</button> </div>
3、发布信息
在用户登录后,即可发布信息。
<form action="{{ url_for('question') }}" method="post"> <h1>发布问答</h1> <div class="input_box"> <label for="questionQuestion">标题:</label> <textarea class="form-control" rows="2" id="questionQuestion" typeof="text" placeholder="请输入标题..." style="width: 500px" name="title"></textarea></div> <div class="input_box"> <label for="questionDetail">内容:</label> <textarea class="form-control" rows="6" id="questionDetail" typeof="text" placeholder="请输入内容..." style="width: 500px" name="detail"></textarea></div> <div id="error_box"><br></div> <div class="input_box"> <button onclick="fnQuestion()">发布</button> </div> </form>
4、搜索功能
通过输入关键字,可以通过精确查询搜索所有发过的信息,包括标题,内容,和评论。
@app.route('/search/') def search(): sousuo = request.args.get('sousuo') author = User.query.all() ydfabu = Fabu.query.filter(Fabu.yuedu > 5).all() fabus = Fabu.query.filter( or_( # 两种查询条件 Fb.title.contains(sousuo), # contains模糊查询 Fb.detail.contains(sousuo) ) ).order_by('-creat_time') return render_template('daohang.html', fb=fb, zz=zzr, yd=yd)
5、个人中心
个人中心根据session的ID进入,里面展示了用户发表的信息,用户收藏和评论的文章,以及用户的个人信息。
<h3 class="text-center">个人信息</h3> <ul> <li>用户:{{ username }}</li> <li>编号:{{ userid }}</li> <li>昵称:{{ nickname }}</li> <li>头像:<img src="https://ss1.bdstatic.com/70cFvXSh.jpg" ></li> <li>文章:{{ fabus|length }}篇</li> <li>评论:{{ comments|length }}条</li> <li>收藏文章:{{ shoucang|length }}篇</li> </ul>
四、数据库设计
使用工具:Navicat for MySQL
class User(db.Model): # 创建类User
__tablename__ = 'user' # 类对应的表名user
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # autoincrement自增长
username = db.Column(db.String(20), nullable=False) # nullable是否为空
_password = db.Column(db.String(200), nullable=False) # 密码加密内部使用
nickname = db.Column(db.String(20), nullable=True)
@property # 定义函数,需要用属性时可以用函数代替
def password(self): # 密码加密外部使用
return self._password
@password.setter
def password(self, row_password): # 密码进来时进行加密,generate_password_hash是一个密码加盐哈希函数,生成的哈希值可通过check_password_hash()进行验证。
self._password = generate_password_hash(row_password)
def check_password(self, row_password): # check_password_hash函数用于验证经过generate_password_hash哈希的密码。若密码匹配,则返回真,否则返回假。
result = check_password_hash(self._password, row_password)
return result
class Fabu(db.Model): # 问答
__tablename__ = 'fabu'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
detail = db.Column(db.Text, nullable=False)
leixing = db.Column(db.String(20), nullable=True)
creat_time = db.Column(db.DateTime, default=datetime.now) # 提交时间会自己赋值
author_id = db.Column(db.Integer, db.ForeignKey('user.id')) # 数据类型是db.Integer,db.ForeignKey参数指定外键是哪个表中哪个id
author = db.relationship('User', backref=db.backref('fabu')) # 建立关联,其author属性将返回与问答相关联的用户实例,相当于数据库中的表连接
# 第一个参数表明这个关系的另一端是哪个类,第二个参数backref,将向User类中添加一个fabu属性,从而定义反向关系,这一属性可访问Fabu类,获取的是模型对象
yuedu = db.Column(db.Integer, nullable=False)
class Comment(db.Model): # 评论
__tablename__ = 'comment'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id'))
creat_time = db.Column(db.DateTime, default=datetime.now)
detail = db.Column(db.Text, nullable=False)
fabu = db.relationship('Fabu',
backref=db.backref('comments', order_by=creat_time.desc)) # order_by=creat_time.desc按时间降序
author = db.relationship('User', backref=db.backref('comments'))
class Shoucang(db.Model): # 收藏
__tablename__ = 'shoucang'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id'))
fabu = db.relationship('Fabu', backref=db.backref('shoucangs'))
author = db.relationship('User', backref=db.backref('shoucangs'))
class Dianzang(db.Model): # 点赞
__tablename__ = 'dianzang'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
fabu_id = db.Column(db.Integer, db.ForeignKey('fabu.id'))
fabu = db.relationship('Fabu', backref=db.backref('dianzangs'))
author = db.relationship('User', backref=db.backref('dianzangs'))
五、系统实现的关键算法与数据结构
Python+Flask+MysqL的web建设技术。
六、成品展示
首页
注册页
登录页
登录前
登陆后
个人信息
详情页
收藏页