Django项目之个人网站

关注公众号“轻松学编程”了解更多。
Github地址:https://github.com/liangdongchang/MyWeb.git

感兴趣的可以fork或star一下

功能模块二:投票

一、说明

功能:用户对喜欢的编程语言进行投票、留言。

用户点击投票时“投票按钮”会变成红色,票数加1,再次点击时会取消投票操作,按钮变成绿色,票数减1(相当于没有投票)。

技术:缓存、分页、反向解析、重定向。

二、界面
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 vote.html
{% extends 'SitesApp/base.html' %}
{% block title %}
<title>投票</title>
{% endblock %}
{% block content %}
{% ifequal ip '127.0.0.1' %}
<a href="{% url 'sitesApp:addCandidate' %}" style="color: green;margin: 0 0 10px;display: inline-block">新增候选者</a>
{% endifequal %}
<div style="width: 800px;margin: 0 auto;">
{% for condidate in page.object_list %}
<div style="display: inline-block;position: relative;">
<span style="color: red;">{{ condidate.cName }}</span>
<img src="/static/SitesApp/imgs/language/{{ condidate.cIcon }}" style="height: 60px;margin: 0 10px 10px;display: block;" title="{{ condidate.cDeclaration }}">
<button class="vote" condidateId="{{ condidate.id }}" name="{{ condidate.cName }}" voteCid="{{ condidate.id }}" style="background-color: #95D195;" title="投票"><span class=" glyphicon glyphicon-thumbs-up " ></span></button>
<button class="chat" chatCid="{{ condidate.id }}" title="留言"><span class="glyphicon glyphicon-envelope" title="留言"></span></button>
<br>
票数:<span id="{{ condidate.id }}" class="badge">{{ condidate.cVotes }}</span>
</div> {% endfor %}
<br> {# 分页器:html内容拷贝于bootstrap网站-组件-分页#}
{# bootstrap是一整套成熟经典的页面组件框架#}
<nav aria-label="Page navigation">
<ul class="pagination">
{# 上一页按钮#}
{# 如果有上一页#}
{% if page.has_previous %}
<li>
{# 点击超链接,对上一页的页面发起访问#}
<a href="{% url 'sitesApp:vote' page.previous_page_number %}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li> {# 如果没有上一页#}
{% else %}
{# 当没有上一页时,阅读bootrap文档得知,对当前li使用disabled样式#}
<li class="disabled">
{# href="#",处于禁用状态的按钮被点击时直接跳转本页#}
<a href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a> </li>
{% endif %}
{# 页码按钮#}
{# 遍历传入的页码范围#}
{% for p in pagerange %}
{# 如果页码=当前页页码#}
{% ifequal p currentpage %}
{# 被选中的页码具有高亮效果,阅读bootrap文档得知,对当前li使用active样式#}
{# {% url 'sitesApp:vote' p %} 点击页码,对第p页的路由发起访问#}
<li class="active"><a href="{% url 'sitesApp:vote' p %}">{{ p }}</a></li>
{% else %}
{# 非当前页页码普通显示#}
<li><a href="{% url 'sitesApp:vote' p %}">{{ p }}</a></li>
{% endifequal %}
{% endfor %} {# 下一页按钮#}
{% if page.has_next %}
<li>
{# 点击超链接,对下一页的页面发起访问#}
<a href="{% url 'sitesApp:vote' page.next_page_number %}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a></li>
{% else %}
{# 当没有下一页时,阅读bootrap文档得知,对当前li使用disabled样式#}
<li class="disabled">
{# href="#",处于禁用状态的按钮被点击时直接跳转本页#}
<a href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div> <div style="height: 280px;width:800px;margin: 0 auto;">
<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 style="width: 150px;">{{ message.crDateTime|date:'Y-m-d H:i' }}</td>
<td style=" padding: 0 20px;">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 type="text/javascript">
/* $(this)当前被点击的元素 <a style='color:black;'>你好</a>
element.css('color','red')设置元素的CSS样式
element.css('color')获取元素的CSS样式 <a href='xxx'>你好</a>
element.attr('href','http://www.baidu.com')设置元素的html属性
element.attr('href')获取元素的html <a href='xxx'>你好</a>
element.html('我好')设置元素的html节点内容
element.html()获取元素的html节点内容 */
$(function($){
<!--如果用户已经投过票,投票按钮就显示红色-->
var isVoteLists = {{ isVoteLists }}
{# console.log(isVoteLists);#}
{#如果用户已经点击了就显示红色#}
$('*[voteCid]').each(function () {
var voteCid = $(this);
if( $.inArray(parseInt(voteCid.attr('voteCid')), isVoteLists) >= 0){
voteCid.css("background", "#D1191B");
}
}); $('.vote').click(function () {
var voteBtn = $(this);
var cid = voteBtn.attr('voteCid');
var spanGnum = voteBtn.next().next().next();
$.getJSON(
"{% url 'sitesApp:addVote' %}",
{"cid": cid},
function (data) {
console.log(data);
{# 投票成功#}
if(data['status'] == 1){
voteBtn.css("background", "#D1191B");
}else if(data['status'] == 2){
{#用户再次点击就显示绿色#}
voteBtn.css("background", "#95D195");
}
spanGnum.html(data['poills'] ); window.location.href = '{% url "sitesApp:vote" %}';
}
)
}); $('.chat').click(function () {
var voteBtn = $(this);
var whoId = voteBtn.attr('chatCid');
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){
window.location.href = '{% url "sitesApp:vote" %}';
}
}
});
} else {
alert("留言失败");
}
});
});
</script>
{% endblock %}
2 路由处理(V)
2.1 项目下的总路由
urlpatterns = [
url('^app/',include('SitesApp.urls',namespace='sitesApp'))
]
2.2 子应用下的路由
 	# 投票
url(r'^vote/(?P<pageNum>\d+)?', views.vote,name='vote'),
# 增加投票
url(r'^addVote/', views.addVote, name='addVote'),
3、视图函数处理(Views)
3.1 投票主页
# 投票
def vote(request,pageNum):
print('要第几页数据',pageNum)
if not pageNum:
pageNum = 1
# 获取用户IP
ip = getUserIP(request)
# 把本机地址传到页面,页面才能显示新增候选者按钮
dictData = {'ip': '127.0.0.1'} # 获取候选者
candidates = Candidate.cManager.filter(cVoteType__vType__contains='编程').order_by('-cVotes')
# 用户投票结果列表
isVoteLists = []
for candidate in candidates:
print(candidate.cName,'的票数为',candidate.cVotes)
# 判断当前IP今天是否已经对该候选者投过票
isVote = opeVoteRecordT.query(vCandidateId_id=candidate.id,isDelete=0,vTypeId_id=candidate.cVoteType_id, vComIP=ip,
vDate=datetime.datetime.now().__format__('%Y-%m-%d')) if isVote.exists():
isVoteLists.append(candidate.id) dictData['isVoteLists'] = isVoteLists
# 获取留言信息
chatRecords = ChatRecord.crManager.filter(crType=candidates.first().cVoteType_id)
if chatRecords.exists():
dictData['messages'] = chatRecords # 构建分页器对象,candidates=候选者列表,5=每页显示的个数
paginator = Paginator(candidates, 5)
# 获取第n页的页面对象
page = paginator.page(pageNum) # Paginator和Page的常用API
# page.previous_page_number()
# page.next_page_number()
# page.has_previous()
# page.has_next() # 构造页面渲染的数据
'''
渲染需要的数据:
- 当前页的候选者对象列表
- 分页页码范围
- 当前页的页码
''' if request.method == 'GET':
# 当前页的候选者对象列表
dictData['page'] = page
# 分页页码范围
dictData['pagerange'] = paginator.page_range
# 当前页的页码
dictData['currentpage'] = page.number return render(request, 'SitesApp/vote.html', context=dictData)
3.2 增加票数
# 增加投票数
def addVote(request):
cid = request.GET.get('cid',None)
if not cid:
return JsonResponse({'status':0,'msg':'no cid'})
# 获取候选者信息
candidate = Candidate.cManager.get(pk=cid)
poills = candidate.cVotes
ip = getUserIP(request)
data = {'status': 0,'msg':'vote failed'}
# 判断当前IP今天是否已经对该候选者投过票
isVote = opeVoteRecordT.query(vCandidateId_id=cid,vTypeId__vType__contains='编程',vComIP=ip,vDate=datetime.datetime.now().__format__('%Y-%m-%d')).first()
# isDelete初始值为0,表示记录没有被逻辑删除,用户再次点击投票就把记录删除,isDelete置为1
if isVote:
data['status'] = 2
data['msg'] = 'already voted'
# isDelete为True表示取消投票
if isVote.isDelete:
poills += 1
else:
poills -= 1
# 修改投票记录
if not opeVoteRecordT.modify(isVote.id,isDelete= not isVote.isDelete):
print('修改投票记录失败')
return JsonResponse(data)
print('现在是取消(True)还是投票(False)',isVote.isDelete)
# 修改候选者票数
if not opeCandidateT.modify(candidate.id,cVotes=poills):
print('修改候选者记录失败')
return JsonResponse(data) else:
user=getUser(request)
if not user:
return JsonResponse(data)
# 增加投票记录
if not opeVoteRecordT.add(vUserId_id=user.id,vCandidateId_id=candidate.id,vComIP=ip,vTypeId_id=candidate.cVoteType_id,vPolls=1,vTimes=1):
return JsonResponse(data)
# 修改候选者票数
if not opeCandidateT.modify(candidate.id,cVotes=candidate.cVotes+1):
return JsonResponse(data)
data['status'] = 1
data['msg'] = 'success'
data['poills'] = poills
return JsonResponse(data)

######3.3 业务逻辑

1、用户第一次访问投票主页时,从服务器获取候选者信息,显示候选者图片和票数。

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

3、点击投票按钮时,把候选者id传给服务器,服务器增加投票记录,修改票数,把处理结果返回给客户端。投票按钮显示红色,显示最新票数。

4、如果用户再次点击投票按钮,服务器则把该候选者的票数减1,把投票记录设置为逻辑删除isDelete=1.投票按钮显示绿色。

5、留言内容限定为40字。
6、判断当前ip是否为127.0.0.1,如果是就显示“新增候选者”按钮,可以通过此按钮添加候选者,其它ip则不行。
7、如果当前ip在用户表中找不到,就把当前Ip在后台自动添加到用户表。

后记

【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。

也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!

公众号


关注我,我们一起成长~~

Django项目-个人网站之投票模块的更多相关文章

  1. Django项目-个人网站之事项模块

    Django项目之个人网站 关注公众号"轻松学编程"了解更多. Github地址:https://github.com/liangdongchang/MyWeb.git 感兴趣的可 ...

  2. Django项目: 3.用户注册功能

    本章内容的补充知识点 导入库的良好顺序: 1.系统库 2.django库 3.自己定义的库(第三方库) redis缓存数据库的数据调用速度快,但是不利于长时间保存. mysql用于长时间存储,但是调用 ...

  3. 在nginx上部署django项目--------Gunicorn+Django+nginx+mysql

    一.安装nginx 以前的博客我有写,这里就不写了 http://www.cnblogs.com/wt11/p/6420442.html 二.安装mysql 我用的mysql5.7  64位的二进制包 ...

  4. Django项目实践4 - Django网站管理(后台管理员)

    http://blog.csdn.net/pipisorry/article/details/45079751 上篇:Django项目实践3 - Django模型 Introduction 对于某一类 ...

  5. Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块

    Python第十三天   django 1.6   导入模板   定义数据模型   访问数据库   GET和POST方法    SimpleCMDB项目   urllib模块   urllib2模块 ...

  6. 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程

    点击了解更多Python课程>>> 零基础入门Python实战:四周实现爬虫网站 Django项目视频教程 适用人群: 即将毕业的大学生,工资低工作重的白领,渴望崭露头角的职场新人, ...

  7. Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用

    Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...

  8. Django项目中模板标签及模板的继承与引用【网站中快速布置广告】

    Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...

  9. Django项目打分系统

    Django项目之个人网站 关注公众号"轻松学编程"了解更多. Github地址:https://github.com/liangdongchang/MyWeb.git 感兴趣的可 ...

随机推荐

  1. C 面向对象编程 --- 一模块的串口协议解析

    // 任务目的// 解析串口收到的54个字节.这54个字节包含了8个车道的5大信息以及校验信息.// 实现了查询每条车道包含了哪些信息. #include <stdio.h>#includ ...

  2. Tomcat 第六篇:类加载机制

    1. 引言 Tomcat 在部署 Web 应用的时候,是将应用放在 webapps 文件夹目录下,而 webapps 对应到 Tomcat 中是容器 Host ,里面的文件夹则是对应到 Context ...

  3. javaagent+asm破解censum

    内容介绍 最近在学习字节码相关知识,了解到通过ASM字节码改写技术来做破解一些软件破解,非常感兴趣,本文记录一下破解 Censum的过程(仅个人学习使用). 之前也写过一篇暴力破解Censum的文章, ...

  4. IPA的动态库注入+企业重签名过程

    [摘录]之前在进行iOS测试过程中由于要获取一定数据信息,因此需要对原本的安装包进行代码注入并且重新打包安装,因此就需要使用重签名策略,在此进行分享,希望大家可以使用其中的方法来运用到自身的项目中. ...

  5. Python操作图像

    安装Pillow pip install Pillow 打开图像 from PIL import Image img = Image.open("./lena.tiff") 保存图 ...

  6. MeteoInfoLab脚本示例:线性拟合

    MeteoInfoLab提供一个线性拟合函数linregress,参数是参与拟合的两个数据序列,返回拟合的斜率.截距和相关系数.有了上述拟合参数可以用polyval函数生成拟合数据(直线).然后可以将 ...

  7. linux(centos8):安装kubernetes worker节点并加入到kubernetes集群(kubernetes 1.18.3)

    一,安装kubernetes前的准备工作      安装前的准备工作(master\worker都要进行)      参见: https://www.cnblogs.com/architectfore ...

  8. nginx安全:配置网站图片防盗链

    一,为什么要做防盗链? 1,什么是盗链? 比如某人有一个A网站, 他不愿自己存储图片,(因为磁盘和带宽都有成本) 就在自己A网站的页面上直接插入B网站的图片, 从而为自己吸引流量,这就是盗链 2,为什 ...

  9. Python之tuple元组详解

    元组:有序,一级元素不可以修改.不能被增加或删除(元组是可迭代对象) 一般写法括号内最后面加个英文逗号用来区分: test  =  (,) test1 = (11,22,) 例: test = (12 ...

  10. Java9系列第8篇-Module模块化编程

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...