Django项目-个人网站之打分模块

Django项目之个人网站

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

感兴趣的可以fork或star一下

这里写图片描述

功能模块三:打分

一、说明

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

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

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

二、界面
1、投票

这里写图片描述

三、代码
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、如果用户已经打过分,打分按钮显示红色,再点击时提示已经打过分。

扫描二维码关注公众号,回复: 1801328 查看本文章

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

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

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

猜你喜欢

转载自blog.csdn.net/lm_is_dc/article/details/80657417