开发文档和代码展示(部分)
开发文档:
请参照往期组会博客:→ 【攻城喵】博客汇总目录
github的commit: → 攻城喵git的commit
我们全组在master的分支中共commit了这么多次
部分代码展示:
【首先需要说明,我们的项目完全开源,所有代码均可在上边的github地址中fork到,故在此只选择部分代码进行展示】
一、部分前端js:
①更改头像功能:
②聊天界面的发送和接收功能:
③朋友列表响应效果
二、部分前端html和css:
①个人主页(需要配套css和js,请到bbs.hanhaixingyun.cn中查看):
<!DOCTYPE html><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>个人页面-瀚海星云BBS</title> <meta name="keywords" content="喵"> <meta name="description" content="喵"> <link rel="shortcut icon" href="img/ustc.png"> <link href="css/bootstrap.min.css?v=3.3.6" rel="stylesheet"> <link href="css/font-awesome.css" rel="stylesheet"> <link href="css/style_35_common.css" rel="stylesheet"> <link href="css/style_35_forum_viewthread.css" rel="stylesheet"> <link href="css/animate.css" rel="stylesheet"> <link href="css/style.css?v=4.1.0" rel="stylesheet"> <script type="text/javascript" src="js/origional.js"></script> </head> <body class="sky-bg"> <div class="wrapper wrapper-content animated fadeInUp"> <div class="row"> <div class="col-sm-12"> <div class="ibox"> <div class="ibox-content"> <div class="row"> <div class="col-sm-12"> <div class="m-b-md"> <a href="x_edit_person_demo.html" class="btn btn-blue pull-right atest">修改资料</a> <div class="boxT"> <img alt="image" src="img/boy_hat.jpg"> <h2>章豪</h2> </div> </div> <dl class="dl-horizontal"> <dt>状态:</dt> <dd><span class="label label-info">在线</span> </dd> </dl> </div> </div><!--头像和用户名--> <div class="row"> <div class="col-sm-5"> <dl class="dl-horizontal"> <dt>昵称:</dt> <dd>XXX</dd> <dt>性别:</dt> <dd>女</dd> <dt>等级:</dt> <dd>6</dd> <dt>上站次数:</dt> <dd>66</dd> <dt>发帖数:</dt> <dd>666</dd> <dt>积分:</dt> <dd>6666</dd> </dl> </div> <div class="col-sm-7" id="cluster_info"> <dl class="dl-horizontal"> <dt>最近登录时间:</dt> <dd>2018年 5月31日 18:03</dd> <dt>最近离站时间:</dt> <dd>2018年 5月31日 18:08</dd> <dt>创建于:</dt> <dd>2018年 3月16日 03:01</dd> <dt>在线总时长:</dt> <dd>6小时6分钟6秒</dd> <dt>关注用户:</dt> <dd class="project-people"> <a href="personal_page_show_demo.html" class="atest"> <img alt="image" class="img-circle" src="img/boy_sport.jpg"> </a> <a href="personal_page_show_demo.html" class="atest"> <img alt="image" class="img-circle" src="img/boy_glasses.jpg"> </a> <a href="personal_page_show_demo.html" class="atest"> <img alt="image" class="img-circle" src="img/girl_silent.jpg"> </a> <a href="personal_page_show_demo.html" class="atest"> <img alt="image" class="img-circle" src="img/girl_shorthair.jpg"> </a> <a href="personal_page_show_demo.html" class="atest"> <img alt="image" class="img-circle" src="img/girl_rollhair.jpg"> </a> </dd> </dl> </div> </div><!--状态信息--> <div class="row"> <div class="col-sm-12"> <dl class="dl-horizontal"> <dt>经验值</dt> <dd> <div class="progress progress-striped active m-b-sm"> <div style="width: 66%;" class="progress-bar progress-bar-success1" style="background-color: dodgerblue"></div> </div> <small>经验值: <strong>66%</strong>(66666/100000)</small> </dd> </dl> </div> </div><!--经验值--> <div class="row"> <div class="col-sm-12"> <dl class="dl-horizontal"> <dt>个人说明/签名档</dt> <dd> 《他改变了中国:???传》,2005年中文版、英文版全球同步发行。该书是一部人物传记,作者为美国作家罗伯特·劳伦斯·库恩(Robert Lawrence Kuhn),中文翻译本署名“谈峥,于海江等”。作者长期关注中国,关注???,并向???的亲属、好友及有关工作人员进行了深入细致的采访,掌握了大量第一手资料,在此基础上写成本书。 这本传记介绍了???的人生历程,尤其是阐述和评价了传主担任中国主要领导人的10多年中创立的历史功绩。在着重于国事活动的同时,也广泛涉及传主家庭生活、业余爱好、人品风格等方方面面,多角度、多侧面地展现了传主的风采。 </dd> </dl> </div> </div><!--个人说明--> <div class="row m-t-sm"> <div class="col-sm-12"> <div class="panel blank-panel selected"> <div class="panel-heading"> <div class="panel-options"> <ul class="nav nav-tabs"> <li><a href="#tab-1" data-toggle="tab">我关注的</a> </li> <li class=""><a href="#tab-2" data-toggle="tab">我的动态</a> </li> <li class=""><a href="#tab-3" data-toggle="tab">我的收藏</a> </li> <li class=""><a href="#tab-4" data-toggle="tab">回复我的</a> </li> </ul> </div> </div><!--标签--> <div class="panel-body"> <div class="tab-content"> <div class="tab-pane active" id="tab-1"> <div class="feed-activity-list"> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div style="margin: 0 auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right text-muted">2018-5-28</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">benerboba</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="x_huitie_demo.html" style="left: auto;margin: 0 auto;font-size: medium"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">章豪信号与系统4.3</p> </div> </div> </div> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right text-muted">2018-6-17</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">???</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="x_huitie_demo.html" style="left: auto;margin: 0 auto;font-size: medium"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">章豪信号与系统考了95,他的微机原理考了96,这个学期,到现在为止,它考了3门4.3,他太厉害了,他好巨啊,他太强了,豪哥年年起飞。</p> </div> </div> </div> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div class="pull-left" style="margin: 7px auto;float: left;position: relative;margin-left: 10px;margin-right: 10px"> <a class="btn btn-xs btn-success"> <i class="fa fa-star"></i> 精 </a> </div> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right text-muted">2018-6-17</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">????</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="x_huitie_demo.html" style="left: auto;margin: 0 auto;font-size: medium"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">Jerry马上就挂满20学分啦!</p> </div> </div> </div> </div> <div class="text-center"> <div class="btn-group"> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-left"></i> </button> <button class="btn btn-white active" style="color: #0a6aa1">1</button> <button class="btn btn-white" style="color: #0a6aa1">2</button> <button class="btn btn-white" style="color: #0a6aa1">3</button> <button class="btn btn-white" style="color: #0a6aa1">4</button> <button class="btn btn-white" style="color: #0a6aa1">5</button> <button class="btn btn-white" style="color: #0a6aa1">6</button> <button class="btn btn-white" style="color: #0a6aa1">7</button> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-right"></i> </button> </div> </div> </div> <div class="tab-pane" id="tab-2"> <div class="feed-activity-list"> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right">2018-7-11</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">Jerry</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="#" style="left: auto;margin: 0 auto;font-size: medium;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">C罗走了?伤心的要死</p> </div> </div> </div> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div class="pull-left" style="margin: 7px auto;float: left;position: relative;margin-left: 10px;margin-right: 10px"> <a class="btn btn-xs btn-success"> <i class="fa fa-star"></i> 精 </a> </div> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right">2018-7-12</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">????</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="#" style="left: auto;margin: 0 auto;font-size: medium;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">官方:C罗加盟尤文图斯!</p> </div> </div> </div> </div> <div class="text-center"> <div class="btn-group"> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-left"></i> </button> <button class="btn btn-white active" style="color: #0a6aa1">1</button> <button class="btn btn-white" style="color: #0a6aa1">2</button> <button class="btn btn-white" style="color: #0a6aa1">3</button> <button class="btn btn-white" style="color: #0a6aa1">4</button> <button class="btn btn-white" style="color: #0a6aa1">5</button> <button class="btn btn-white" style="color: #0a6aa1">6</button> <button class="btn btn-white" style="color: #0a6aa1">7</button> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-right"></i> </button> </div> </div> </div> <div class="tab-pane" id="tab-3"> <div class="feed-activity-list"> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div class="pull-left" style="margin: 7px auto;float: left;position: relative;margin-left: 10px;margin-right: 10px"> <a class="btn btn-xs btn-success"> <i class="fa fa-star"></i> 精 </a> </div> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right">2018-7-12</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">????</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="#" style="left: auto;margin: 0 auto;font-size: medium;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">官方:C罗加盟尤文图斯!</p> </div> </div> </div> <div class="feed-element" style="cursor: pointer"> <div class="media-body"> <div style="margin: 1px auto;float: right;position: relative;left: -10px;"> <div style="margin: 0 auto"> <small class="pull-right">2018-6-17</small> </div> <div style="margin: 0 auto"> <a href="" class="pull-right"> <span class="glyphicon glyphicon-user" style="font-size: xx-small"></span> <i style="font-size: xx-small">???</i> </a> </div> </div> <div class="text-muted1 well well0 atest" href="#" style="left: auto;margin: 0 auto;font-size: medium;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">章豪信号与系统考了95,他的微机原理考了96,这个学期,到现在为止,它考了3门4.3……</p> </div> </div> </div> </div> <div class="text-center"> <div class="btn-group"> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-left"></i> </button> <button class="btn btn-white active" style="color: #0a6aa1">1</button> <button class="btn btn-white" style="color: #0a6aa1">2</button> <button class="btn btn-white" style="color: #0a6aa1">3</button> <button class="btn btn-white" style="color: #0a6aa1">4</button> <button class="btn btn-white" style="color: #0a6aa1">5</button> <button class="btn btn-white" style="color: #0a6aa1">6</button> <button class="btn btn-white" style="color: #0a6aa1">7</button> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-right"></i> </button> </div> </div> </div><!--动态形式--> <div class="tab-pane" id="tab-4"> <div class="feed-activity-list"> <div class="feed-element"> <a href="" class="pull-left"> <img alt="image" class="img-circle" src="img/a2.jpg"> </a> <div class="media-body "> <strong>ZH</strong> 回复了你 <br> <div class="text-muted1 well well0 atest" href="#" style="cursor: pointer;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">法国应该可以打赢比利时的</p> </div> </div> </div> <div class="feed-element"> <a href="" class="pull-left"> <img alt="image" class="img-circle" src="img/a3.jpg"> </a> <div class="media-body "> <strong>ZH</strong> 回复了你 <br> <div class="text-muted1 well well0 atest" href="#" style="cursor: pointer;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">以后就是尤文球迷啦!</p> </div> </div> </div> <div class="feed-element"> <a href="" class="pull-left"> <img alt="image" class="img-circle" src="img/a5.jpg"> </a> <div class="media-body "> <strong>MRC</strong> 回复了你 <br> <div class="text-muted1 well well0 atest" href="#" style="cursor: pointer;"> <p class="contentwidth" onmouseover="overShow(this,event)" onmouseout="outHide()">别太难过了,该走的总是要走的</p> </div> </div> </div> </div> <div class="text-center"> <div class="btn-group"> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-left"></i> </button> <button class="btn btn-white active" style="color: #0a6aa1">1</button> <button class="btn btn-white" style="color: #0a6aa1">2</button> <button class="btn btn-white" style="color: #0a6aa1">3</button> <button class="btn btn-white" style="color: #0a6aa1">4</button> <button class="btn btn-white" style="color: #0a6aa1">5</button> <button class="btn btn-white" style="color: #0a6aa1">6</button> <button class="btn btn-white" style="color: #0a6aa1">7</button> <button class="btn btn-white" type="button" style="color: #0a6aa1"><i class="fa fa-chevron-right"></i> </button> </div> </div> </div> </div> </div> </div> </div> <div id="showDiv" style="position: absolute; float: top;background-color: white; border: 1px solid black;"> </div> </div> </div> </div> </div> </div> </div> <!-- 全局js --> <script src="js/jquery.min.js?v=2.1.4"></script> <script src="js/bootstrap.min.js?v=3.3.6"></script> <!-- 自定义js --> <script src="js/content.js?v=1.0.0"></script> <script src="js/origional.js"></script> </body> </html>
②发帖页面(需要配套css和js,请到bbs.hanhaixingyun.cn中查看):
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>瀚海星云BBS-发帖</title> <meta name="keywords" content=""> <meta name="description" content=""> <link rel="shortcut icon" href="img/ustc.png"> <link href="css/bootstrap.min.css?v=3.3.6" rel="stylesheet"> <link href="css/font-awesome.css?v=4.4.0" rel="stylesheet"> <link href="css/plugins/iCheck/custom.css" rel="stylesheet"> <link href="css/plugins/summernote/summernote.css" rel="stylesheet"> <link href="css/plugins/summernote/summernote-bs3.css" rel="stylesheet"> <link href="css/animate.css" rel="stylesheet"> <link href="css/style.css?v=4.1.0" rel="stylesheet"> </head> <body class="gray-bg"> <div class="wrapper wrapper-content" style="padding: 4vmin 2vmin 2vmin 2vmin"> <div class="row" style="margin-right: -1.5vmin;margin-left: -1.5vmin"> <div class="col-sm-3" > <div class="ibox float-e-margins" style="margin-bottom: 2.5vmin"> <div class="ibox-content mailbox-content" style="display: block;padding: 1vmin;font-size: 1.8vmin"> <div class="file-manager"> <a class="btn btn-block btn-info compose-mail" href="x_bankuai_demo.html" style="padding: 0.8vmin 1vmin">发帖</a> <div class="space-25" style="margin: 2.5vmin 0"></div> <ul class="folder-list m-b-md" style="padding: 0;margin-bottom: 2vmin"> <li> <a href="x_caogao_demo.html"> <i class="fa fa-file-text-o"></i> 草稿 <span class="label label-info pull-right">2</span> </a> </li> </ul> <h3 class="font-bold">分区</h3> <div class="btn-group"> <button data-toggle="dropdown" class="btn btn-info dropdown-toggle">A区<span class="caret"></span> </button> <ul class="dropdown-menu" style="left: 0;right: auto"> <li><a href="buttons.html#">1</a> </li> <li><a href="buttons.html#">2</a> </li> <li><a href="buttons.html#">3</a> </li> <li><a href="buttons.html#">4</a> </li> </ul> </div> <div class="btn-group"> <button data-toggle="dropdown" class="btn btn-info dropdown-toggle">B区<span class="caret"></span> </button> <ul class="dropdown-menu" style="left: 0;right: auto"> <li><a href="buttons.html#">1</a> </li> <li><a href="buttons.html#">2</a> </li> <li><a href="buttons.html#">3</a> </li> <li><a href="buttons.html#">4</a> </li> </ul> </div> <div class="btn-group"> <button data-toggle="dropdown" class="btn btn-info dropdown-toggle">C区 <span class="caret"></span> </button> <ul class="dropdown-menu"> <li><a href="buttons.html#">1</a> </li> <li><a href="buttons.html#">2</a> </li> <li><a href="buttons.html#">3</a> </li> <li><a href="buttons.html#">4</a> </li> </ul> </div> <div class="btn-group"> <button data-toggle="dropdown" class="btn btn-info dropdown-toggle">D区 <span class="caret"></span> </button> <ul class="dropdown-menu"> <li><a href="buttons.html#">1</a> </li> <li><a href="buttons.html#">2</a> </li> <li><a href="buttons.html#">3</a> </li> <li><a href="buttons.html#">4</a> </li> </ul> </div> <div class="btn-group"> <button data-toggle="dropdown" class="btn btn-info dropdown-toggle">E区 <span class="caret"></span> </button> <ul class="dropdown-menu"> <li><a href="buttons.html#">1</a> </li> <li><a href="buttons.html#" >2</a> </li> <li><a href="buttons.html#">3</a> </li> <li><a href="buttons.html#">4</a> </li> </ul> </div> <div class="clearfix"></div> </div> </div> </div> </div> <div class="col-sm-9 animated fadeInRight" style="height: 100%"> <div class="mail-box-header" style="padding: 3vmin 2vmin 2vmin 2vmin"> <h2> 发帖 </h2> </div> <div class="mail-box" style="margin-bottom: 2vmin"> <div class="mail-body" style="margin-bottom: 0.5vmin;padding: 2vmin"> <form class="form-horizontal" method="get"> <div class="form-group" style="margin-bottom: 0.5vmin"> <label class="col-sm-2 control-label">主题:</label> <div class="col-sm-10"> <input type="text" class="form-control" value=""> </div> </div> </form> </div> <div class="mail-text h-200"> <div class="summernote"> </div> <div class="clearfix"></div> </div> <div class="mail-body text-right tooltip-demo" style="padding: 2vmin"> <a href="x_mailbox_demo.html" class="btn btn-sm btn-info" data-toggle="tooltip" data-placement="top" title="Send"><i class="fa fa-reply"></i> 发表</a> <a href="x_mailbox_demo.html" class="btn btn-white btn-sm" data-toggle="tooltip" data-placement="top" title="Discard email"><i class="fa fa-times"></i> 放弃</a> <a href="x_mailbox_demo.html" class="btn btn-white btn-sm" data-toggle="tooltip" data-placement="top" title="Move to draft folder"><i class="fa fa-pencil"></i> 存为草稿</a> </div> <div class="clearfix"></div> </div> </div> </div> </div> <!-- 全局js --> <script src="js/jquery.min.js?v=2.1.4"></script> <script src="js/bootstrap.min.js?v=3.3.6"></script> <!-- 自定义js --> <script src="js/content.js?v=1.0.0"></script> <!-- iCheck --> <script src="js/plugins/iCheck/icheck.min.js"></script> <!-- SUMMERNOTE --> <script src="js/plugins/summernote/summernote.min.js"></script> <script src="js/plugins/summernote/summernote-zh-CN.js"></script> <script> $(document).ready(function () { $('.i-checks').iCheck({ checkboxClass: 'icheckbox_square-green', radioClass: 'iradio_square-green', }); $('.summernote').summernote({ lang: 'zh-CN' }); }); var edit = function () { $('.click2edit').summernote({ focus: true }); }; var save = function () { var aHTML = $('.click2edit').code(); //save HTML If you need(aHTML: array). $('.click2edit').destroy(); }; </script> </body> </html>
三、部分后端数据库
①用户model
1 class common_member(AbstractUser): 2 # uid = models.IntegerField(max_length=12, primary_key=True) 3 # email = models.EmailField() 4 username = models.CharField(max_length=30, unique=True) 5 stu_num = models.CharField(max_length=10, null=True) 6 login_times = models.IntegerField(default=0) 7 dept_choices = ( 8 ('000', '少年班学院'), 9 ('001', '数学科学院'), 10 ('203', '物理学院'), 11 ('204', '管理学院'), 12 ('206', '化学学院'), 13 ('210', '信息科学技术学院'), 14 ('215', '计算机科学与技术学院'), 15 ('jwc', '教务处'), 16 17 ) 18 department = models.CharField(max_length=30, null=True, choices=dept_choices) 19 birthday = models.DateField(default=date.today) 20 # password = models.CharField(max_length=20) 21 # status = models.BooleanField(default=True) # 判断用户是否已经删除 1=未删除 0=删除 22 slug = models.SlugField(max_length=100, default=slugify(str(username)), allow_unicode=True) 23 portrait = models.ImageField(upload_to='portraits', null=True, blank=True) 24 temp_portrait = models.ImageField(upload_to='portraits', null=True, blank=True) # 临时预览头像 25 points = models.IntegerField(default=0) # 积分 26 gender_choices = (('m', '男'), ('f', '女')) 27 gender = models.CharField(max_length=1, default='m', choices=gender_choices) # 性别 true为男 28 show_gender = models.BooleanField(default=True) # 是否显示 29 profile = models.CharField(default='', max_length=280) 30 email_status = models.BooleanField(default=False) # email是否经过验证 1=验证通过 0=未验证 31 username_validator = BbsUsernameValidator 32 posts = models.IntegerField(default=0) # 帖子数 33 following = models.IntegerField(default=0) # 关注者数 34 followed = models.IntegerField(default=0) # 被关注数 35 followers = models.ManyToManyField('common_member', symmetrical=False, through='follower_pair') 36 section_followed = models.ManyToManyField('section.SectionForum', symmetrical=False, through='section_follow_pair') 37 38 def follow_list(self): 39 return ','.join([i.username for i in self.followers.all()]) 40 41 # avatarstatus = models.BooleanField(default=False) # 是否有头像 1=已上传 0=未上传 42 # accessmasks = models.BooleanField(default=True) # 访问权限 43 # allowadmincp = models.BooleanField(default=False) # 管理权限 44 # freeze = models.BooleanField(default=False) # 是否被冻结 45 # adminid = models.IntegerField(null=True) # 管理组id 1=管理员 2=超级版主 3=版主 46 # regdate = models.DateField() # 注册时间 47 # newpm = models.IntegerField() # 新短消息数量 48 # newprompt = models.IntegerField() # 新提醒数目 49 def __str__(self): 50 return self.username 51 52 def save(self, *args, **kargs): # ④ 53 self.slug = slugify(self.username) # ⑤ 54 super(common_member, self).save(*args, **kargs) 55 56 def get_url(self): # ⑥ 57 return reverse("show_info", args={self.slug})
②帖子model
1 class ArticlePost(models.Model): 2 pid = models.AutoField(primary_key=True, auto_created=True) # 增加一个主键 3 is_school_info = models.BooleanField(default=False) # 是否公告 4 5 author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True) 6 title = models.CharField(max_length=200) 7 body = models.TextField() 8 ueditor_body = UEditorField(width=600, height=300, null=True, toolbars="full", imagePath="images/", filePath="files/", 9 upload_settings={"imageMaxSize": 1204000}, settings={}, verbose_name='内容') 10 isElite = models.BooleanField(default=False) 11 pub_date = models.DateTimeField(auto_now_add=True, editable=True, db_index=True) 12 13 section_belong_fk = models.ForeignKey('section.SectionForum', on_delete=models.CASCADE, null=True) 14 slug = models.SlugField(max_length=500, default=slugify(str(title)), allow_unicode=True) 15 comment_counter = models.IntegerField(default=0) 16 17 users_like = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="articles_like", blank=True) 18 19 likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='likes') 20 21 def __str__(self): 22 return self.title 23 24 def save(self, *args, **kargs): # ④ 25 self.slug = slugify(self.title) # ⑤ 26 super(ArticlePost, self).save(*args, **kargs) 27 28 def get_url(self): # ⑥ 29 return reverse("article_detail", args=[self.pid, self.slug]) 30 31 @property 32 def total_likes(self): 33 """ 34 Likes for the company 35 :return: Integer: Likes for the company 36 """ 37 return self.likes.count() 38 #return int(3)
③板块model
1 class SectionForum(models.Model): 2 section_id = models.AutoField(primary_key=True) # 论坛id 3 # section_up_id = models.IntegerField(default=None, null=True) # 上级论坛id 4 types_choices = ( 5 ('g', 'group'), 6 ('f', 'forum'), 7 ('s', 'sub') 8 ) 9 brief = models.CharField(max_length=140, default=None, null=True) 10 types = models.CharField(max_length=1, choices=types_choices) # 论坛类型 11 name = models.CharField(max_length=50, unique=True) # 论坛名 12 slug = models.SlugField(max_length=500, default=slugify(str(name)), allow_unicode=True) 13 status = models.BooleanField(default=False) 14 display_order_choices = ( 15 ('tim', 'time'), 16 ('pop', 'popularity'), 17 ('tit', 'title') 18 ) 19 display_order = models.CharField(max_length=3, choices=display_order_choices) 20 posts = models.IntegerField(default=0) # 帖子数量 21 todayposts = models.IntegerField(default=0) 22 lastpostid = models.ForeignKey('article.ArticlePost', null=True, default=None, on_delete=models.CASCADE) 23 follower_num = models.IntegerField(default=0) 24 block_choices = ( 25 ('a', u'A区: 部门组织'), 26 ('b', u'B区: 信息论坛'), 27 ('c', u'C区: 我们的家'), 28 ('d', u'D区: 出国留学'), 29 ('e', u'E区: 学术科学'), 30 ('f', u'F区: 文化艺术'), 31 ('g', u'G区: 休闲感性'), 32 ('h', u'H区: 体育健身'), 33 ('i', u'I区: 瀚海特区'), 34 ('j', u'J区: 本站系统'), 35 ) 36 block = models.CharField(max_length=1, choices=block_choices) 37 38 39 class Meta: 40 verbose_name = 'forum' 41 verbose_name_plural = 'forums' 42 43 def __str__(self): 44 return self.name 45 46 def save(self, *args, **kargs): # ④ 47 self.slug = slugify(self.name) # ⑤ 48 super(SectionForum, self).save(*args, **kargs) 49 50 def get_url(self): # ⑥ 51 return reverse("section_all", args={self.slug})
四、部分后端views代码(主要逻辑)
①注册&登录
# 登入操作实现 def login(request): # 如果当前已有用户登入, 则直接跳转到主页 if request.user.is_authenticated: return redirect(reverse('index')) # 当正常访问时, 返回login.html的渲染 if request.method == 'GET': form = UserLoginForm() return render(request, "login_v2_demo.html", {"form": form, "title": u'中国科学技术大学BBS登录'}) else: # 当提交表单时, 判断用户名密码是否正确,正确则返回主页的渲染 # 不正确则返回错误报告 form = UserLoginForm(request.POST) # print(1) if form.is_valid(): username = request.POST.get('username', '') password = request.POST.get('password', '') user = auth.authenticate(username=username, password=password) # print(username, password) if user is not None and user.is_active: # 加密 # usrnm = hashlib.md5('zhanghaodashuaibi'.encode('utf-8')) # usrnm.update(username.encode('utf-8')) # pswd = hashlib.md5('madalaotaiqiangle'.encode('utf-8')) # pswd.update(password.encode('utf-8')) if user.email_status is True: response = redirect(reverse('index')) # response.set_cookie('username', username, # expires=timezone.now()+datetime.timedelta(days=10)) # passwd = common_member.objects.get(username=username).password # response.set_cookie('password', passwd, # expires=timezone.now() + datetime.timedelta(days=10)) auth.login(request, user) user.login_times += 1 user.save() return response else: return render(request, 'login_v2_demo.html', { 'form': form, 'email_not_active': True, "title": u'中国科学技术大学BBS登录', 'password_is_wrong': False, }) else: return render(request, 'login_v2_demo.html', { 'form': form, 'password_is_wrong': True, "title": u'中国科学技术大学BBS登录', 'email_not_active': False, }) else: return render(request, "login_v2_demo.html", {"form": form, "title": u'中国科学技术大学BBS登录'}) # 注册操作实现 def register(request): # global new_account # 当正常访问时候, 返回register.html的渲染 if request.method == 'GET': form = UserRegisterForm() return render(request, "register_demo_v2.html", {"form": form, "title": u"欢迎注册瀚海星云BBS"}) else: # 当提交表单时, 判断用户名是否被注册, 密码是否合法, 再次输入密码是否正确, 是否勾选阅读用户协议 form = UserRegisterForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] password_confirm = form.cleaned_data['password_confirm'] email = form.cleaned_data['email'] confirm_message = True if common_member.objects.filter(username=username): return render(request, "register_demo_v2.html", { "form": form, "title": u"欢迎注册瀚海星云BBS", "user_name_used": True, }) try: password_validation.validate_password(password, username) except ValidationError as err: # print(4) error = err return render(request, "register_demo_v2.html", { "form": form, "title": u"欢迎注册瀚海星云BBS", "password_invalidate": True, "error_msg": error }) if password != password_confirm: return render(request, "register_demo_v2.html", { "form": form, "title": u"欢迎注册瀚海星云BBS", "pw_confirm_error": True, }) if confirm_message is False: return render(request, "register_demo_v2.html", { "form": form, "title": u"欢迎注册瀚海星云BBS", "not_confirmed": True, }) new_account = common_member() new_account.username = username new_account.password = make_password(password) new_account.email = email new_account.portrait.name = "portraits/default_img/boy_glasses.jpg" # 新加 待测试 new_account.save() # token = account_activation_token.make_token(new_account) # return render(request, "register.html", { # "form": form, # "title": u"欢迎注册翰海星云BBS", # "waiting": True, # }) return redirect(reverse('wait_email', args=(username, ))) # 邮箱验证 # hostname = 'roarcannotprogramming.com:8017' # activation_url = hostname + reverse('verify_user', args=(username, )) # mail_text = u'<p>To 亲爱的同学:</p> <br/> <br/> <p>欢迎您使用瀚海星云, 现在仍然是测试版,' \ # u' 若发现漏洞请联系此邮箱</p> <br/><br/><p>您的验证网址 # 为</p><br/><br/><br/><a href="'+activation_url+'">'+activatio # n_url+'</a><br/><br/><br/><br/><br/><br/>'\ # u'<p>From 攻城喵团队</p>' # msg = EmailMultiAlternatives(u'瀚海星云-邮箱验证', mail_text, 'paulzh@mail.ustc.edu.cn', [email, ]) # msg.content_subtype = "html" # # try: # msg.send() # except BadHeaderError: # new_account.delete() # return render(request, "register.html", {"form": form, "title": u"欢迎注册瀚海星云 # BBS", "error_unknown": True}) # # return render(request, "register.html", { # "form": form, # "title": u"欢迎注册翰海星云BBS", # "success": True, # }) else: return render(request, "register_demo_v2.html", {"form": form, "title": u"欢迎注册瀚海星云BBS", "error_unknown": True}) # issue 1: 用户名首字母大写
②板块显示&翻页
@login_required(login_url='/login/') def section_all(request, section_slug): section = SectionForum.objects.filter(slug=section_slug).first() posts = ArticlePost.objects.filter(section_belong_fk=section).order_by('-pub_date')[0:2*Num_per_page] post_num = ArticlePost.objects.filter(section_belong_fk=section).count() context = { 'section': section, 'post_num': post_num, 'posts': posts, } return render(request, 'x_bankuai_demo.html', context) @login_required(login_url='/login/') def section_open_posts_list(request): # print("what") sec_slug = request.GET.get("sec_slug") section = SectionForum.objects.filter(slug=sec_slug).first() page = request.GET.get("page") # present active page button post_num = ArticlePost.objects.filter(section_belong_fk=section).count() page_num = math.ceil(post_num/Num_per_page) if page == '': page = '1' page = int(page) if request.GET.get('isDecPage') == '1': page = max(page-1, 1) elif request.GET.get('isIncPage') == '1': page = min(page+1,page_num) if request.GET.get("isElite") == '0': posts = ArticlePost.objects.filter(section_belong_fk=section).order_by('-pub_date')[Num_per_page*(page-1): Num_per_page*page] else: posts = ArticlePost.objects.filter(section_belong_fk=section, isElite=True).order_by('-pub_date')[Num_per_page*(page-1): Num_per_page*page] # find the pages to display pages_to_show = [] start = max(min(page - 3, page_num-6), 1) end = min(max(page + 3, 7), page_num) for pa in range(start, end+1): pages_to_show.append(str(pa)) post_list = [] for po in posts: item = {} item = item.fromkeys(('pub_date', 'author', 'author_url', 'url', 'title')) item['author_url'] = po.author.get_url() item['pub_date'] = po.pub_date.strftime('%a %d/%m/%y') item['author'] = po.author.username item['url'] = po.get_url() item['title'] = po.title item['isElite'] = str(po.isElite) post_list.append(item) context = { 'pages_to_show': pages_to_show, 'page_active': str(page), 'post_list': post_list } return JsonResponse(context)
③发帖
@login_required(login_url='/login') @csrf_exempt def article_post(request): sections = SectionForum.objects.all() if request.method == "POST": article_post_form = ArticlePostForm(data=request.POST) if article_post_form.is_valid(): cd = article_post_form.cleaned_data #try: new_article = ArticlePost() new_article.author = request.user new_article.title = cd.get('title') new_article.ueditor_body = cd.get('content') new_article.section_belong_fk = SectionForum.objects.get(name=request.POST.get('secsb')) new_article.save() # 更新用户动态 new_action = common_member_action_log() new_action.uid = request.user new_action.pid = new_article new_action.action = 'post' new_action.save() #url = reverse('') url = reverse('article_detail', kwargs={'pid':new_article.pid,'slug':new_article.slug}) #print(url) return HttpResponseRedirect(url) #return HttpResponse('1') #except: #return HttpResponse("2") else: return HttpResponse("3") else: article_post_form = ArticlePostForm() context = {'sections': sections} return render(request, "x_fatie_demo.html", {"article_post_form":article_post_form, "sections":sections})