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. MySQL 5.7安装与配置

    Windows 一.到MySQL官网下载压缩版本,下载后文件为mysql-5.7.20-winx64.zip,解压到D:\develop\mysql-5.7.20-winx64.   二.在系统变量P ...

  2. 开源后台系统*mee-admin*

    mee-admin开源后台系统 Preface 这是一个开放的时代,我们不能总是把东西揣在口袋里面自己乐呵. 也正如名言所说的"如果你有两块面包,你当用其中一块去换一朵水仙花" 所 ...

  3. SPI应用 用SPI控制一个数字电位器

    Controlling a Digital Potentiometer Using SPI In this tutorial you will learn how to control the AD5 ...

  4. 版本控制系统之git

    一.简介 git是Linux内核项目发起者linus用C语言写的,主要用来做项目的版本控制追踪:git是无中心节点的分布式版本控制系统,也是目前很流行的版本控制系统:其安装简单,使用简单:相比传统的c ...

  5. 从零开始学python之Python安装和环境配置

    Python 3适用于Windows,Mac OS和大多数Linux操作系统.即使Python 2目前可用于许多其他操作系统,有部分系统Python 3还没有提供支持或者支持了但被它们在系统上删除了, ...

  6. 萌新学python

    python python安装 进入官网http://www.python.org/download/ 下载 我下的是3.6.6大家可以根据需要下载(3.x和2.x不兼容请小心) 之后安装就可以了 p ...

  7. ORA-28001: the password has expired 密码已过期

    ORA-28001: the password has expiredORA-28001: 密码已过期 Cause:       The user's account has expired and ...

  8. js 递归的理解

    友情提示:阅读本文需花 3分钟左右! 递归函数必须接受参数. (比如我要递归谁?) 在递归函数的定义初始,应该有一个判断条件,当参数满足这个条件的时候,函数停止执行,并返回值.(指定退出条件,否则就会 ...

  9. Chrome浏览器调试移动端网页,测试人员也可以轻松debug

    现在的产品,移动端应用占据很大市场,在测试过程中,就会测试各种各样的移动端页面.测试过程,或多或少会发现些问题,无非就是前端.后端问题.后端接口问题,可以利用工具:Fiddler或charles抓包查 ...

  10. 网络io控制器

    网络io控制器 网络io控制器 ZLAN6842,ZLAN6844是8路远程网络IO控制器.含有8路DI.8路DO,8路AI输入.其中DI支持干节点和湿节点,带光耦隔离:DO为继电器输出,具有5A 2 ...