美文网首页python从小白到白痴
基于Django的打分系统

基于Django的打分系统

作者: lm_is_dc | 来源:发表于2020-03-07 22:45 被阅读0次

    Django项目之个人网站

    Github地址:https://github.com/liangdongchang/MyWeb.git

    感兴趣的可以fork或star一下

    image

    功能模块三:打分

    一、说明

    功能:用户对进行分享的同学打分、留言。

    用户点击打分时,“打分按钮”会变成红色,分数加上用户填写的分数,并显示打分人数、总分数、平均分,。

    技术:缓存、中间件、反向解析、重定向。

    二、界面
    1、投票
    image
    三、代码
    1、前端(T)
    1.1 base.html
    {#    父模板base.html#}
    {% load static %}
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
     <meta charset="UTF-8">
    {#    响应式web设计,自适应浏览器大小#}
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta name="save" content="history">
    
     {% block title %}
     <title>首页</title>
     {% endblock %}
     {% block link %}
     {% endblock %}
    
     <link href="{% static 'SitesApp/css/reset.css' %}" rel="stylesheet">
     <link href="{% static 'SitesApp/css/sitesAppCss.css' %}" rel="stylesheet">
    {#    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">#}
    {#    <script src="https://cdn.bootcss.com/jquery/1.12.0/jquery.min.js"></script>#}
    {#    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>#}
     <link href="/static/SitesApp/css/bootstrap.min.css" rel="stylesheet">
     {% block style %}
    
     {% endblock %}
     <script src="/static/SitesApp/js/jquery.min.js"></script>
     <script src="/static/SitesApp/js/bootstrap.min.js"></script>
    
     {% block script %}
     <script type="text/javascript"></script>
     {% endblock %}
    
    </head>
    <body style="background-color: #E6E6FA;">
    <a href="{% url 'sitesApp:vote' 1 %}">hhhhh</a>
    <div class="box">
     <div class="header">
    
     <ul class="nav nav-pills navbar faq-tabbable">
     <li role="presentation" class="active"><a href="{% url 'sitesApp:home' %}">首页</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:vote' 1 %}">投票</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:grade' %}">打分</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:review' %}">回顾</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:blog' %}">博客</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:dataBank' %}">资料</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:forum' %}">论坛</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:mine' %}">我的</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:login' %}">登录</a></li>
     <li role="presentation"><a href="{% url 'sitesApp:register' %}">注册</a></li>
    
     </ul>
     </div>
     <div class="time" >
     <span id="mytime"></span>
     </div>
     <div class="content" style="position: relative;">
     {% block content %}
     这家伙很懒,还没开始开发...~_~
     {% endblock %}
    
     </div>
     <div class="footer">
     {% block footer %}
     开发者 LDC
     {% endblock %}
    
     </div>
    </div>
    <script type="text/javascript">
     $(function ($) {
     {#    导航栏按钮渲染#}
     $(".faq-tabbable").find("li").each(function () {
     var a = $(this).find("a:first")[0];
     if ($(a).attr("href") === location.pathname) {
     $(this).addClass("active");
     } else {
     $(this).removeClass("active");
     }
     });
     });
     {#实时显示时间#}
     function showTime(){
     nowtime=new Date();
     year=nowtime.getFullYear();
     month=nowtime.getMonth()+1;
     date=nowtime.getDate();
     document.getElementById("mytime").innerText=year+"年"+month+"月"+date+" "+nowtime.toLocaleTimeString();
     }
    
     <!--定时刷新时间-->
     setInterval("showTime()",1000);
    </script>
    
    </body>
    </html>
    
    1.2 grade.html
    {% extends 'SitesApp/base.html' %}
    
     {% block title %}
     <title>打分</title>
     {% endblock %}
     {% block link %}
     <link href="https://cdn.bootcss.com/bootstrap-select/1.12.4/css/bootstrap-select.min.css" rel="stylesheet">
     <link href="/static/SitesApp/css/bootstrap-select.min.css" rel="stylesheet">
    
     {% endblock %}
     {% block content %}
     <div style="width: 400px;margin: 0 auto;">
     <img style="margin: 0 0 5px; height: 100px;display: inline-block;" src="/static/SitesApp/imgs/think.jpg" title="思考">
     <div class="form-group">
    
     <span class="glyphicon glyphicon-user"></span>
     <strong style="color: #222;font-size: 16px;">分享者:</strong>
    
     {% if who %}
     <input list="browsers" id="whoId" class="selectpicker show-tick"  value="{{ who.cName }}" onchange="inputSelect()">
     {% else %}
     <input list="browsers" id="whoId" class="selectpicker show-tick" placeholder="请选择一位分享者" onchange="inputSelect()">
     {% endif %}
     <datalist id="browsers">
     {% for c in candidates %}
     <option value="{{ c.cName }}" data-value="{{ c.cName }}"  data-id="{{ c.id }}">{{ c.id }}</option>
     {% endfor %}
     </datalist>
     {% ifequal ip '127.0.0.1'  %}
     <a href="{% url 'sitesApp:addCandidate' %}" style="color: green;">新增分享者</a>
     {% endifequal %}
     </div>
     </div>
     <div style="width: 400px;margin: 0 auto;">
     <table>
     <thead>
     <tr>
     <th style="font-size: 16px;width: 100px;text-align: center">当前总分数</th>
     <th style="font-size: 16px;width: 100px;text-align: center">班级总人数</th>
     <th style="font-size: 16px;width: 100px;text-align: center">打分人数</th>
     <th style="font-size: 16px;width: 100px;text-align: center">平均分</th>
     </tr>
     </thead>
     <tbody>
     <tr>
     {% if grade %}
     <td>{% widthratio grade.num 1 grade.avg %}</td>
     <td>60</td>
     <td>{{ grade.num }}</td>
     <td>{{ grade.avg }}</td>
     {% else %}
     <td>0</td>
     <td>60</td>
     <td>0</td>
     <td>0</td>
     {% endif %}
    
     </tr>
     </tbody>
     </table>
     </div>
    
     {% csrf_token %}
     <button class="vote"  style="margin: 10px 10px 0"   value="{{ who.id }}"  name="{{ who.cName }}" title ="{{ who.cDeclaration }}"><span style="color: #D2691E;">打分</span></button>
     <button class="chat" value="{{ who.id }}"  name="{{ who.cName }}" title ="{{ who.cDeclaration }}"><span style="color: #D2691E;">留言</span></button>
     <button class="reload" style="margin: 10px 10px 0"   title ="{{ who.cDeclaration }}"><span style="color: #D2691E;">刷新</span></button>
    
     <div style="margin: 0 auto;width: 1200px;">
     <div style="height: 280px;width:400px;text-align: center;float: left">
     <h2 style="height: 20px; width: 150px;margin-bottom: 15px;">打分区</h2>
     <div id="chat" style="height: 200px; overflow: auto;width: 350px;border: 2px solid black;border-radius: 5px;">
     <table >
     <thead>
     <tr class="danger">
     <th style="width: 30px;text-align: center;">序号</th>
     <th style="width: 80px;text-align: center;">时间</th>
     <th style="width: 50px;text-align: center;">打分者</th>
     <th style="width: 40px;text-align: center;">分数</th>
    
     </tr>
     </thead>
     <tbody >
     {% if voteRecords %}
     {% for voteRecord in voteRecords %}
     <tr class="{% cycle 'active' 'success' 'warning' 'info' %}">
     <td> {{ forloop.counter }} </td>
     <td >{{ voteRecord.vDate|date:'Y-m-d ' }}</td>
     <td style=" padding: 0 20px;">guest{{ forloop.counter }} </td>
     <td style=" padding: 0 20px;">{{  voteRecord.vPolls }}</td>
     </tr>
     {% endfor %}
     {% else %}
     <tr>
     <td colspan="4">无数据</td>
     </tr>
     {% endif %}
     </tbody>
     </table>
     </div>
     </div>
     </div>
     <div style="height: 280px;width:600px;margin: 0 0 0 40px;text-align: center;float: left;">
     <h2 style="height: 20px; width: 100px;margin-bottom: 15px;">留言区</h2>
     <div id="chat" style="height: 200px; width: 800px;overflow: auto;border: 2px solid black;border-radius: 5px;">
     <table >
     <thead>
     <tr class="danger">
     <th style="width: 40px;text-align: center;">序号</th>
     <th style="width: 80px;text-align: center;">留言时间</th>
     <th style="width: 60px;text-align: center;">留言者</th>
     <th style="width: 80px;text-align: center;">标题</th>
     <th style="width: 550px;text-align: center;">内容</th>
     </tr>
     </thead>
     <tbody >
     {% if messages %}
     {% for message in messages %}
     <tr class="{% cycle 'active' 'success' 'warning' 'info' %}">
     <td> {{ forloop.counter }} </td>
     <td >{{ message.crDateTime|date:'H:i:s' }}</td>
     <td style=" padding: 0 40px;">guest{{ forloop.counter }} </td>
     <td style=" padding: 0 20px;">评价</td>
     <td style=" padding: 0 20px;">{{ message.crInfo }}</td>
    
     </tr>
     {% endfor %}
    
     {% else %}
     <tr>
     <td colspan="4">无数据</td>
     </tr>
     {% endif %}
     </tbody>
     </table>
     </div>
     </div>
    
     {% endblock %}
     {% block script %}
     <script src="https://cdn.bootcss.com/bootstrap-select/1.12.4/js/bootstrap-select.min.js"></script>
     <script src="https://cdn.bootcss.com/bootstrap-select/1.12.4/js/i18n/defaults-zh_CN.min.js"></script>
    
     <script src="/static/SitesApp/js/bootstrap-select.min.js"></script>
     <script src="/static/SitesApp/js/defaults-zh_CN.min.js"></script>
    
     <script type="text/javascript">
     jQuery(function ($) {
     $('#whoId').focus();
     {#如果用户已经打分就把打分按钮显示红色#}
     {% ifequal done 1 %}
     $('.vote').css('background-color','red').find('span').css('color','#080808');
     {% endifequal %}
     var whoId = 0;
     var times = {{ times }};
     $("button").click(function () {
     whoId = checkInput();
     if(whoId === 0){
     return
     }
    {#                alert(whoId);#}
     var btnThis = $(this);
     var btnType = $(this).attr("class");
     var name = $(this).attr("name");
     <!--打分-->
     if(btnType == 'vote'){
     var judge1 = prompt("请给"+name+"打分(0-100分)");
     grades = parseInt(judge1);
     if( !checkNumber(judge1) || grades < 0 || grades > 100){
     alert("分数范围为0-100");
     }
     else {
     var url = '{% url "sitesApp:addGrade" %}';
     $.ajax({
     type:"POST",
     url: url,
     data:{'whoId':whoId,'times': times,'grades':grades},
     dataType: "json",
     success: function (res) {
     {#alert(res);#}
     if (res['status'] == 1) {
     alert("打分成功!");
     {#把打分按钮显示红色#}
     btnThis.css('background-color','red').find('span').css('color', '#080808');
     } else {
     alert("您今天已经对" + name + " 打过分了!");
     }
     url = "/app/grade/?whoId="+whoId+"&times="+times;
     window.location.href = url;
     },error: function (e) {
     alert(e.responseText);
     }
     });
     }
     }else if(btnType == 'chat'){
     var judge = prompt(name + "留言区(最多40个字)");
     if (judge && judge.length <= 40) {
     url = '{% url "sitesApp:chat" %}';
     $.ajax({
     type:"POST",
     url:url,
     data:{"cInfo":judge, "whoId":whoId},
     dataType:"json",
     success: function(res) {
     if(res['status'] == 1){
     url = "/app/grade/?whoId="+whoId+"&times="+times;
     window.location.href = url;
     }
     }
     });
     } else {
     alert("留言失败");
     }
     }else if(btnType == 'reload'){
     url = "/app/grade/?whoId="+whoId+"&times="+times;
     window.location.href = url;
     }else{
     }
     });
     });
     function inputSelect(){
     var whoId = checkInput();
     var times = {{ times }};
     var url = "/app/grade/?whoId="+whoId+"&times="+times;
     window.location.href = url;
     }
    
     function checkInput() {
     var input_select=$("#whoId").val();
     var option = $('option');
     var option_length=option.length;
     var option_id='';
     for(var i=0;i<option_length;i++){
     var option_value=option.eq(i).attr('data-value');
     if(input_select==option_value){
     option_id=$("option").eq(i).attr('data-id');
     break;
     }
     }
     if(option_id != 0){
     return option_id;
     }else {
     alert("请选择一位分享者!!");
     return 0;
     }
     }
     //验证字符串是否是数字
     function checkNumber(theObj) {
     var reg = /^[0-9]+.?[0-9]*$/;
     return reg.test(theObj);
     }
     function showTime(){
     nowtime=new Date();
     year=nowtime.getFullYear();
     month=nowtime.getMonth()+1;
     date=nowtime.getDate();
     document.getElementById("mytime").innerText=year+"年"+month+"月"+date+" "+nowtime.toLocaleTimeString();
     }
     <!--定时刷新时间-->
     setInterval("showTime()",1000);
     </script>
     {% endblock %}
    
    2 路由处理(V)
    2.1 项目下的总路由
    urlpatterns = [
     url('^app/',include('SitesApp.urls',namespace='sitesApp'))
    ]
    
    2.2 子应用下的路由
    # 打分旧地址
     url(r'^shareNav/', views.shareNav,name='shareNav'),
     # 打分首页
     url(r'^grade/', views.grade,name='grade'),
     # 增加分数
     url(r'^addGrade/', views.addGrade,name='addGrade'),
    
    3、视图函数处理(Views)
    3.1 打分主页
    # 打分
    @csrf_exempt
    def grade(request):
     print('来到了这里')
     vtype = opeVoteTypeT.query(vType__contains='打分').first()
     candidates = Candidate.cManager.filter(cVoteType_id=vtype.id).order_by('cPinyin')
     dictData = {'candidates':candidates}
     ip = getUserIP(request)
     whoId = request.GET.get('whoId', None)
     times = request.GET.get('times', None)
     print('要谁的数据',whoId)
     if whoId and whoId != '0':
     # 判断用户是否已经打分,
     isVote = opeVoteRecordT.query(vTimes=times, vCandidateId_id=whoId, vComIP=ip,
     vDate=datetime.datetime.now().__format__('%Y-%m-%d')).first()
     if isVote:
     # 用户已经打分,打分按钮就显示红色
     dictData['done'] = 1
     candidate = candidates.get(id=whoId)
     dictData['who'] = candidate
     print('候选者的名字',candidate.cName)
     # 获取打分记录
     voteRecords = opeVoteRecordT.query(vCandidateId_id=whoId,vTimes=times,vDate=datetime.datetime.now().__format__('%Y-%m-%d'))
     if voteRecords.exists():
     dictData['voteRecords'] = voteRecords
     # 统计分数
     dictData['grade'] = voteCount(voteRecords)
     for k, v in dictData['grade'].items():
     print(k, v)
     # 获取留言信息
     now = datetime.datetime.now()
     start = now - datetime.timedelta(hours=23, minutes=59, seconds=59)
     chatRecords = ChatRecord.crManager.filter(crTopic=whoId,crDateTime__gt=start,crType=candidate.cVoteType_id)
     if chatRecords.exists():
     dictData['messages'] = chatRecords
    
     if ip == '127.0.0.1':
     dictData['ip'] = ip
     dictData['times'] = 1
     return render(request, 'SitesApp/grade.html',context=dictData)
    
    3.2 增加分数
    # 增加分数
    @csrf_exempt
    def addGrade(request):
     print('***********************************')
     whoId = request.POST.get('whoId', None)
     times = request.POST.get('times', None)
     grades = request.POST.get('grades', None)
     data = {'status': 0, 'msg': 'no whoId'}
     if not whoId:
     return JsonResponse(data)
    
     # 获取候选者信息
     candidate = Candidate.cManager.get(id=whoId)
    
     # 获取用户IP
     ip = getUserIP(request)
     user = getUser(request)
    
     # 判断用户是否已经打分,
     isVote = opeVoteRecordT.query(vTimes=times, vCandidateId_id=whoId, vComIP=ip,
     vDate=datetime.datetime.now().__format__('%Y-%m-%d')).first()
     if isVote:
     print('已经投过票了')
     return JsonResponse({'status': 0, 'msg': 'already grade'})
    
     # 若用户还没有打分就添加打分记录
     if not opeVoteRecordT.add(vUserId_id=user.id, vCandidateId_id=candidate.id, vComIP=ip,
     vTypeId_id=candidate.cVoteType_id, vPolls=grades, vTimes=times):
     print('新增打分记录出错')
     return JsonResponse({'status': 0, 'msg': 'add voteRecord faild'})
     #候选者打分人数加1
     if not opeCandidateT.modify(candidate.id, cVotes=candidate.cVotes + 1):
     print('修改候选者记录出错')
     return JsonResponse({'status': 0, 'msg': 'modify candidateRecord faild'})
     print('给谁打分', whoId, '第几轮', times, '多少分:', grades)
     print('运行到这里啦')
     data = {'status': 1, 'msg': 'success'}
     print(type(data),'***',data)
     return JsonResponse(data)
    
    3.3 留言
    # 留言
    @csrf_exempt
    def chat(request):
     cInfo = request.POST.get('cInfo')
     whoId = request.POST.get('whoId')
     print('给谁留言',whoId)
     # 通过用户IP查找用户的名字
     ip = getUserIP(request)
     user = getUser(request)
    
     # 查找候选者
     candidate = Candidate.cManager.get(pk=whoId, isDelete=0)
     if opeChatRecordT.add(crUserId_id=user.id,crNickName = user.uNickName,crIP = ip,crInfo = cInfo,crTopic = candidate.id,crType = candidate.cVoteType_id):
     return JsonResponse({'status': 1, 'msg': 'success'})
     return JsonResponse({'status': 0, 'msg': 'faild'})
    
    3.4 业务逻辑

    1、用户第一次访问打分主页时,从服务器获取候选者信息加载到下拉框中。

    2、用户选择候选者后,从服务器获取当天的分数和留言信息加载到打分区和留言区。

    3、点击打分按钮时,把候选者id和分数传给服务器,服务器增加打分记录,修改分数,把处理结果返回给客户端。

    4、如果用户已经打过分,打分按钮显示红色,再点击时提示已经打过分。

    5、留言内容限定为40字。

    6、判断当前ip是否为127.0.0.1,如果是就显示“新增候选者”按钮,可以通过此按钮添加候选者,其它ip则不行。

    7、如果当前ip在用户表中找不到,就把当前Ip在后台自动添加到用户表。

    相关文章

      网友评论

        本文标题:基于Django的打分系统

        本文链接:https://www.haomeiwen.com/subject/cepkdhtx.html