def process_request(self, request): if request.path in LOGIN_VISIT: utoken = request.COOKIES.get('utoken', None) if not utoken: # 用户的请求是否需要在登录状态下才能查看 if len(VISIT_PATH.keys()) > 1000: VISIT_PATH.clear() VISIT_PATH[getUserIP(request)] = request.path print('VISIT_PATH[getUserIP(request)]', VISIT_PATH[getUserIP(request)]) return redirect(reverse('SitesApp:login'))
def vote(request, pageNum): # print('要第几页数据', pageNum) if not pageNum: pageNum = 1 # 获取用户IP ip = getUserIP(request) # 把本机地址传到页面,页面才能显示新增候选者按钮 dictData = {'userName': getUser(request).uName} # 获取候选者 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)
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)
def register(request): if request.method == 'GET': return render(request, 'SitesApp/register.html') else: # 获取用户输入的用户名、昵称、密码、验证码、上传的头像 uname = request.POST.get('uname', None) unick = request.POST.get('unick', None) upwd = request.POST.get('upwd', None) vcode = request.POST.get('vcode', None) uip = getUserIP(request) # 拿到用户上传的文件数据,类型是框架类InMemoryUploadedFile uiconFile = request.FILES.get('uicon', None) # <class 'django.core.files.uploadedfile.InMemoryUploadedFile'> # print(uname, unick, upwd, vcode, uiconFile, type(uiconFile)) # 手动存储上传的文件 # 自定义文件位置 # if uiconFile: # fp = os.path.join(MEDIA_ROOT, 'x-' + uiconFile.name) # # 写入文件 # with open(fp, 'wb') as file: # # 逐"桶"读取上传的文件数据,并写入本地文件 # for buffer in uiconFile.chunks(): # file.write(buffer) # 校验验证码 # 从session中获取正确的验证码 sessVcode = request.session.get('vcode', None) # 比较用户输入的验证码与正确的验证码是否匹配 # 事先全部转换为小写形式,这样用户可以忽略大小写 if vcode and sessVcode and vcode.lower() == sessVcode.lower(): user = User() user.uName = uname user.uNickName = unick user.uIP = uip # 对密码做消息摘要(目的是避免明文存储) user.uPwd = useMd5(upwd) # 将上传过来的文件直接赋值给用户的ImageField字段uicon # 框架会自动将图片存储在MEDIA_ROOT中 if uiconFile: user.uIcon = uiconFile # 把数据写进数据库 try: user.save() return JsonResponse({'status': 1, 'ret': 'register success!'}) except BaseException as e: # print(e) pass return JsonResponse({'status': 0, 'ret': '输入信息有误!'})
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'})
def addGrade(request): 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)
def getUser(request): user = checkLogin(request) # 如果用户已经登录就返回该用户 if user: # print('用户已经登录', user) return user ip = getUserIP(request) # print('获取用户ip', ip) # 如果用户已存在就返回该用户 user = User.uManager.filter(uName=ip) # print('根据ip获取到的用户', user) if user.exists(): return user.first() # 如果用户不存在就添加该用户 opeUserT.add(uName=ip, uIP=ip) # 获取用户并返回 return User.uManager.get(uName=ip)
def grade(request): dictData = {} vtype = opeVoteTypeT.query(vType__contains='打分').first() if vtype: candidates = Candidate.cManager.filter(cVoteType_id=vtype.id).order_by('cPinyin') else: return render(request, 'SitesApp/grade.html', context=dictData) dictData = {'candidates': candidates} ip = getUserIP(request) whoId = request.GET.get('whoId', None) times = request.GET.get('times', None) 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 # 获取打分记录 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) # 获取留言信息 now = datetime.datetime.now() start = now - datetime.timedelta(hours=now.hour, minutes=now.minute, seconds=now.second, microseconds=now.microsecond) chatRecords = ChatRecord.crManager.filter(crTopic=whoId, crDateTime__gt=start, crType=candidate.cVoteType_id) if chatRecords.exists(): dictData['messages'] = chatRecords dictData['userName'] = getUser(request).uName dictData['times'] = 1 return render(request, 'SitesApp/grade.html', context=dictData)
def login(request): if request.method == 'GET': return render(request, 'SitesApp/login.html') else: # 初始化返回信息 respData = {'status': '0', 'ret': '登录失败,输入信息有误!!!'} # 预定义一个最终返回的Response对象(可以动态地为其配置内容,要想勒令客户端做事情必须要有一个Response对象) resp = HttpResponse() # 获取用户输入的用户名、密码、验证码 uname = request.POST.get('uname', None) upwd = request.POST.get('upwd', None) vcode = request.POST.get('vcode', None) # 校验验证码 # 从session中获取正确的验证码 sessVcode = request.session.get('vcode', None) # 比较用户输入的验证码与正确的验证码是否匹配 # 事先全部转换为小写形式,这样用户可以忽略大小写 if vcode and sessVcode and vcode.lower() == sessVcode.lower(): # 对密码做消息摘要 upwd = useMd5(upwd) # 查询名称为uname的用户 user = User.uManager.filter(uName=uname).first() if not user: respData = {'status': '0', 'ret': '用户不存在!!!'} # 检查密码、验证码是否匹配 if user and upwd == user.uPwd: # # 勒令客户端(通过cookie)自己将状态保存起来,过期时间为60秒 # resp.set_cookie('uname',uname,max_age=60*1) # # 让服务端通过session保存用户状态 # 向客户端端要session其实是要存储在cookie中的sessionid # request.session的言下之意是"request.getSessionBySessionid" # request.session['uname'] = uname # request.session['upwd'] = upwd ''' token相当于手动实现的session session将用户状态保存在django_session的表中 token将用户状态保存在何处完全取决于程序媛自己,例如:User表 但务必使保存用户状态的这张表中有用于作为[id/key/信物]的字段(该字段必须唯一),例如:utoken 和session一样,必须在客户端的cookie中存一个相同的[id/key/信物],例如:utoken 如何获取存储的用户状态:先从cookie中拿出utoken,进而查询User表中utoken为xxx的记录,就可以拿到uname了 ''' # 将用户状态保存在token中,让客户端持有一个token,将该token保存在某个表中 # 生成令牌/信物 token = str(uuid.uuid4()) # 将该令牌/信物存储在客户端的cookie中,过期时间一天 resp.set_cookie('utoken', token, expires=60 * 60 * 24) resp.set_cookie('uid', user.id, expires=60 * 60 * 24) # 将同样的信物存一份在服务端的表中 user.uToken = token try: user.save() respData = {'status': '1', 'ret': 'login success!'} # 获取用户访问的路径 visit_path = VISIT_PATH.get(getUserIP(request)) # print('visit_path', visit_path) if visit_path: VISIT_PATH.pop(getUserIP(request)) if not visit_path or visit_path == r'/app/login/': respData['path'] = r'/app/mine/' else: respData['path'] = visit_path # print('VISIT_PATH', VISIT_PATH) except BaseException as e: # print(e) pass respData = {'status': '0', 'ret': '登录失败,输入信息有误!!!'} resp.content = json.dumps(respData) return resp