def modify_personal_information(request): """ 修改个人信息:头像与签名. :param request: :return: """ user = get_user(request) file = request.FILES.get('avatar') # 如果存在file,and表达式才会继续判断.先判断尺寸是否大于2M再判断后缀是否合法. if file and file.size < 2 * 1024**2: suffix = file.name.split('.')[1].lower() if suffix in ['jpg', 'png']: d = save_img(file, filename=f'{user.nickname}.{suffix}', folder='avatar/') # 头像路以static开头而不是/static,和FileField字段的upload_to函数行为保持一致. user.avatar = d['src'][1:] # 获取签名的值. try: signature = request.POST.get('signature', '') user.signature = signature user.save() except: raise Http404('签名过长,最大长度为48个字符.') return HttpResponseRedirect(reverse('user:settings'))
def leave_message(request): """ 接收留言请求视图, 此视图需要登入权限装饰器. :param request: :return: """ to_user = request.POST.get('to_user') to_user = User.objects.filter(nickname=to_user).first() # 判断接受留言用户是否存在 if to_user: # 获取留言内容, 获取留言用户实例. content = request.POST.get('content') user = get_user(request) # 写入留言 并保存 m = Message(sender=user, addressee=to_user, content=content, types='message') m.save() # 如果存在type,那么请求为ajax.返回状态码与用户头像与昵称. if request.POST.get('type'): n = m.sender.nickname a = m.sender.avatar.__str__() return JsonResponse({ 'status': 'ok', 'data': { 'avatar': a, 'name': n } }) return HttpResponseRedirect( reverse('user:user_index', args=[to_user.nickname])) else: return Http404
def bind_email(request): """ 绑定邮箱 message:前台提示绑定结果信息. :param request: :return: """ user = get_user(request) # 当用户已绑定邮箱的情况下,返回邮箱已绑定信息. if user.email: return HttpResponseRedirect( reverse('user:settings') + '?message=bind-email-Already') else: email = request.POST.get('email') code = request.POST.get('Vcode') # 当Vcode创建时间大于5分钟前的时间则Vcode为有效,否则即为无效. v = judgment_code(user_user=user.user, code=code, period_of_validity=5) # 如果user与code匹配,并且Vcode为有效,则表明验证通过.进行邮箱绑定. if v: user.email = email user.save() message = '?message=bind-email-success' # 验证成功立即删除Vcode v.delete() else: message = '?message=code-error' return HttpResponseRedirect(reverse('user:settings') + message)
def modify_password(request): """ 修改密码,需要登入权限 :param request: :return: """ # 获取用户实例 user = get_user(request) password = request.POST.get('password') password_repeat = request.POST.get('password_repeat') # 先判断两次密码是否一致,不一致直接返回错误消息 or 密码不符合LoginForm验证条件 if password != password_repeat or not LoginForm({ 'user': user.user, 'password': password }).is_valid(): return HttpResponseRedirect( reverse('user:settings') + '?message=password_repeatInconsistent') code = request.POST.get('Vcode') # code与有效期都符合条件judgment返回v实例,否则返回None v = judgment_code(user_user=user.user, code=code, period_of_validity=5) if v: # 修改密码,registered()方法将密码加密并且保存数据.最后删除v实例,使code失效. user.password = password user.registered() v.delete() # 密码修改成功,退出登录. return HttpResponseRedirect(reverse('user:logout')) else: # code错误或code已失效,在前台给出错误提示. return HttpResponseRedirect( reverse('user:settings') + '?message=code-error')
def collection(request): """ 收藏话题请求\处理,视图. 如果用户当前未登录,直接返回failure状态码,如果已登录,再继续做判断. :param request: :return: 状态码与相应提示信息通知 """ user = get_user(request) if user: topic = request.GET.get('topic') c = Collection.objects.filter(topic_id_id=topic, user=user).first() if c: # 用户已收藏此话题,当前请求判断为取消收藏.选择删除收藏关系 c.delete() return JsonResponse({ 'status': 'success', 'message': 'cancel-collection' }) else: # 用户未收藏此话题,建立收藏关系 c = Collection(topic_id_id=topic, user=user) c.save() return JsonResponse({ 'status': 'success', 'message': 'collection-success' }) else: return JsonResponse({ 'status': 'failure', 'message': 'collection-failure' })
def settings(request): """ 个人帐号设置界面 :param request: :return: """ user = get_user(request) content = {'title': '账号设置', 'user': user} return render(request, template_name='user/settings.html', context=content)
def mailbox(request): """获取聊天记录与未读消息数量,不要具体内容. :return: 信箱页 """ self = get_user(request) contacts = Message.objects.values( 'addressee', 'sender', 'sender__avatar', 'sender__nickname').filter( addressee=self, addressee_status=False).annotate(count=Count('status')) content = {'title': '信箱', 'contacts': contacts} return render(request, template_name='user/mailbox.html', context=content)
def del_message(request): """修改删除状态为True,因为记录是双向的,所以以此方法做消息删除. :return: """ self = get_user(request) nickname = request.GET.get('del_nickname') Message.objects.filter( sender__nickname=nickname, addressee=self, addressee_status=False).update(addressee_status=True) Message.objects.filter(sender=self, addressee__nickname=nickname, sender_status=False).update(sender_status=True) return JsonResponse({'status': 'ok'})
def comment(request, topic_id): """ 处理评论请求 :param request: :param topic_id: 话题id,定位评论与话题关系 :return: 当请求属于reply回复评论时,返回状态信息等...当请求属于评论时,跳转至话题页面,并携带message信息. """ # 获取user判断评论有效性 obj判断是否为回复 user = get_user(request) content = request.POST.get('comment', None) obj = request.POST.get('reply', None) kwargs = {'reply_obj_id': obj} if obj else {} # 以url参数message=xxx的方式传递给给前台的消息反馈,具体消息在前台js文件内. message = '?' if user: # 当用户帐号未激活时,将评论状态改为待审核,并做出相应提示. if user.level == 0: kwargs.update({'status': False}) message += 'message=comment-level' comment = Comment(user_id=user.user, topic_id_id=topic_id, content=content, **kwargs) comment.save() else: # 获取游客ip message提示评论需要审核 ip = request.META['REMOTE_ADDR'] message += "message=comment-audit" comment = Comment(user_id='AdminAudit', status=False, topic_id_id=topic_id, content=content, ip=ip, **kwargs) comment.save() # 如果有reply对象,请求则为ajax请求,返回前台所需的反馈信息. if obj: # reply回复功能,不允许未登入用户回复, return JsonResponse({ 'status': 'ok', 'user': comment.user.nickname, 'content': comment.content }) else: return HttpResponseRedirect( reverse('topic:discuss', args=[topic_id]) + message)
def get_message(request): """ 按需,获取对话记录. other_side: 对方. :param request: :return:返回状态码\对话集\下次请求数 """ # count:消息按需请求,当前请求次数. count = int(request.GET.get('count')) # self:当前用户id,other_side:对方用户 self = get_user(request) other_side = User.objects.filter( nickname=request.GET.get('other_side')).first() other_side_message = Message.objects.filter(sender_id=other_side, addressee=self) # 将对方发送的消息状态更新为已阅读 other_side_message.update(status=True) reply = Message.objects.filter(sender=self, addressee_id=other_side) # 将对方发送消息与自己发送的消息合并 messages = other_side_message | reply # 按id顺序倒序,等于按发送时间倒序 messages = messages.order_by('-id').values('sender__nickname', 'sender__avatar', 'content', 'create_time') # 取出按需请求次数的指定范围 m = list(messages[count * 10 - 10:count * 10]) # 将datetime类型转为str类型,并格式化. for i in m: i['create_time'] = i['create_time'].strftime('%Y-%m-%d %H:%M') # 前台显示需要反转 m.reverse() # 如果后面还有消息,告诉前台还可以再次请求,否则设置count为小于0的数字,告诉前台后面没有消息了,不可再次请求. if len(messages[count * 10:count * 10 + 10]): count += 1 else: count = -1 return JsonResponse({'status': 'ok', 'messages': m, 'count': count})