python从小白到白痴

基于Django的打分系统

2020-03-07  本文已影响0人  lm_is_dc

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在后台自动添加到用户表。

上一篇下一篇

猜你喜欢

热点阅读