第九届CUIT信息安全大赛正常进行,围观地址:http://hack.myclover.org/

在论坛加了个类似微博的@功能,在回复帖子的时候可以@系统中的用户,被@的用户可以收到自己被@的通知可以做出相应的处理。

关于model

#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import User
import datetime
from geek.geekchallenge.models import *
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
import re
class Reply(models.Model):thread = models.ForeignKey(Thread, verbose_name=u"所属帖子")author = models.ForeignKey(Team, verbose_name=u"回复作者")content = models.TextField(verbose_name=u"回复内容")submit_time = models.DateTimeField(verbose_name=u"发表时间", auto_now_add=True)update_time = models.DateTimeField(verbose_name=u"更新时间", blank=True, null=True, editable=False)events = generic.GenericRelation('Event')def __unicode__(self):return self.submit_time.strftime("%Y-%m-%d %H:%m:%S")class Meta:verbose_name_plural = u"帖子回复"
@receiver(post_save, sender=Reply, dispatch_uid="ashin_unique_identifier")
def post_save_handler(sender, instance, **kwargs):reply = instanceteam_name_pattern = re.compile('(?<=@)(\w+)', re.UNICODE)at_team_names = set(re.findall(team_name_pattern, reply.content))if at_team_names:for at_team_name in at_team_names:if at_team_name != reply.author.user.username:try:at_team = User.objects.get(username=at_team_name)event = Event(author=reply.author.user, event=reply, at_team=at_team)event.save()except:passelif reply.author != reply.thread.author:event = Event(author=reply.author.user, event=reply, at_team=reply.thread.author.user)event.save()
class Event(models.Model):content_type = models.ForeignKey(ContentType, verbose_name=u"被触发的模型")object_id = models.PositiveIntegerField(verbose_name=u"被触发模型ID")author = models.ForeignKey(User, verbose_name=u"事件发起者", related_name="author")event = generic.GenericForeignKey('content_type', 'object_id')at_team = models.ForeignKey(User, verbose_name=u"提到的人", related_name="at_team")#两个外键都指向User必须使用related_name参数submit_time = models.DateTimeField(verbose_name=u"@时间", auto_now_add=True)is_readed = models.BooleanField(verbose_name=u"已读", default=False)is_deleted = models.BooleanField(verbose_name=u"已被删除", default=False)def __unicode__(self):return u"%s在回复%s的帖子《%s》中提到了%s"%(self.author, self.event.thread.author, self.event.thread, self.at_team)class Meta:verbose_name_plural = u"回复新闻"ordering = ["-submit_time"]

在用户按钮处显示有多少条未读@消息

<script>function get_new_at_num(){$.get('/forum/new-at-num/',function(data){if (data != 0){$('#at_tip').text('('+data+'条@我未读)');$('#id_global_at').text(' ('+data+')');}else{$('#at_tip').text('');$('#id_global_at').text('');}window.setTimeout(get_new_at_num, 5000)});};$(function(){get_new_at_num();});
</script>
<div class="btn-group pull-right"><a class="btn dropdown-toggle" data-toggle="dropdown" href=""><i class="icon-user"></i>{% if request.user.is_authenticated %} `request`.`user`.`username` <span id="at_tip"></span>{% else %} 游客{% endif %}<span class="caret"></span></a><ul class="dropdown-menu">{% if request.user.is_authenticated %}<li><a href="/team-info/"><i class="icon-cog"></i> 团队信息</a></li><li><a href="/forum/my-threads/"><i class="icon-th-list"></i> 我的帖子</a></li><li><a href="/forum/at-me/"><i class="icon-envelope"></i> @我的回复<font color="red" id="id_global_at"></font></a></li><li class="divider"></li><li><a href="/accounts/logout/"><i class="icon-off"></i> 退出</a></li>{% else %}<li><a href="/accounts/register/"><i class="icon-pencil"></i> 注册</a></li><li class="divider"></li><li><a href="/accounts/login/"><i class="icon-leaf"></i> 登录</a></li>{% endif %}</ul>
</div><!-- userbtn -->

ajax每隔5秒请求一次服务器返回未读消息的条数,有就显示在页面上

@login_required
def new_at_num(request):unread_count = Event.objects.filter(at_team = request.user, is_deleted=False, is_readed = False).count()return HttpResponse(unread_count)

@的消息页面

页面代码

<div><p>当前位置: <a href="/forum/">论坛首页</a> » @我的回复</p><p>共 <b id="id_all_count">{{results|length}}</b> 条, 未读 <b id="id_unread_count">`unread_count`</b> 条</p>
</div>
<div class="span10">{% if paged_events.object_list %}<table class="table table-hover table-striped"><tr id="id_news_table_head"><th>点击查看@我的回复</th><th>@我的时间</th><th>阅读状态</th><th>操作</th></tr>{% for news in paged_events.object_list %}<tr id="id_news_`news`.`id`"><td><a href="/forum/`news`.`event`.`thread`.`forum`.`id`/`news`.`event`.`thread`.`id`/?reading=`news`.`id`#reply-`news`.`event`.`id`">` news`.`author `在回复` news`.`event`.`thread`.`author`的帖子《`news`.`event`.`thread`.`title`》中提到了您</a></td><td>{{ news.submit_time|date:"Y-m-d H:i:s"}}</td><td>{% if news.is_readed %}已读{% else %}<font color="red" id="id_unread_`news`.`id`">未读</font>{% endif %}</td><td><button id="id_readed_news_`news`.`id`" οnclick="readed_news('`news`.`id`');" class="btn btn-mini btn-success" {% if news.is_readed %}disabled{% endif %}>设为已读</button> <button id="id_delete_news" οnclick="delete_news('`news`.`id`');" class="btn btn-mini btn-warning">删除记录</button></td></tr>{% endfor %}</table>{% endif %}
</div><!--span10-->
<script>function readed_news(id){var url = '/forum/readed-at-me/'+id+'/';$.post(url, {'csrfmiddlewaretoken':'` csrf_token `'}, function(data){if (data=='success'){$('#id_unread_'+id).attr('color', '').text('已读');$('#id_readed_news_'+id).attr('disabled', 'true');$('#id_unread_count').text($('#id_unread_count').text()-1)}else{alert('操作失败!');}});}function delete_news(id){var url = '/forum/delete-at-me/'+id+'/';$.post(url, {'csrfmiddlewaretoken':'` csrf_token `'}, function(data){if(data=='success'){if ($('#id_unread_'+id).text() == '未读'){$('#id_unread_count').text($('#id_unread_count').text()-1)}$('#id_news_'+id).remove();$('#id_all_count').text($('#id_all_count').text()-1)}else{alert('操作失败!');}});}
</script>

处理函数

@login_required
def at_me(request):#最新帖子latest_threads = Thread.objects.all()[:5]#回复事件results = Event.objects.filter(at_team = request.user, is_deleted=False)unread_count = Event.objects.filter(at_team = request.user, is_deleted=False, is_readed = False).count()#分页events_paginator = Paginator(results, 15)try:page = int(request.GET.get('page', 1))except ValueError:page = 1try:paged_events = events_paginator.page(page)except (EmptyPage, InvalidPage):paged_events = events_paginator.page(events_paginator.num_pages)return render_to_response('at-me.html', {"results":results,'unread_count':unread_count, 'latest_threads':latest_threads, "paged_events":paged_events, "events_paginator":events_paginator}, context_instance=RequestContext(request))
@login_required
def readed_news(request, news_id):news = get_object_or_404(Event, id=news_id, at_team=request.user)if request.method == 'POST':news.is_readed=Truenews.save()return HttpResponse("success")return HttpResponse("error")
@login_required
def delete_news(request, news_id):news = get_object_or_404(Event, id=news_id, at_team=request.user)if request.method == 'POST':news.is_deleted = Truenews.save()return HttpResponse("success")return HttpResponse("error")

在回复中@用户

实现代码:

<script src="/static/js/userAutoTips.js"></script>
<style type="text/css" >ol, ul { list-style: none outside none; }.recipients-tips{ font-family:Tahoma, Arial;position:absolute; background:#282828; z-index:2147483647; padding:2px; border:2px solid #33b5e5; display:none;}.recipients-tips li a{display:block; padding:2px 5px; cursor:pointer;}.autoSelected{background:#131517;}
</style>
<script type="text/javascript">userAutoTips({id:'id_content'});
</script>

用了网上找的一个别人写好的只要检测到textarea中有@就会显示列表的代码,自己该了一些设置和获取最近活跃的10位用户

@login_required
def nearest_users(request):threads = Thread.objects.all()replies = Reply.objects.all()users = [thread.author.user.username for thread in threads]users.extend([reply.author.user.username for reply in replies])users = set(users)if request.user.username in users:users.remove(request.user.username)user_name_list = []for user in users:user_name_list.append({}.fromkeys(('user', 'name'), user))show_count = 15if len(user_name_list) > show_count:user_name_list = user_name_list[:show_count]data = simplejson.dumps(user_name_list)return HttpResponse(data, mimetype="application/json")

UserAutoTips.js放到微盘了:

http://vdisk.weibo.com/s/naFdb

文章为阿小信的个人笔记,转载请注明出处。

转载于:https://blog.51cto.com/ashin/1200995

Django模拟新浪微博的@功能相关推荐

  1. pythonurllib微博登陆是什么_python模拟新浪微博登陆功能(新浪微博爬虫)

    1.主函数(WeiboMain.py): import urllib2 import cookielib import WeiboEncode import WeiboSearch if __name ...

  2. php模拟关注微博,PHP基于laravel框架获取微博数据之一 模拟新浪微博登录

    参考资料: http://www.csuldw.com/2016/11/10/2016-11-10-simulate-sina-login/ http://blog.csdn.net/fly_leop ...

  3. php rsa2 微博,PHP 基于laravel框架获取微博数据之一 模拟新浪微博登录

    模拟新浪微博登录是抓取新浪数据的基础,网上的参考资料大多介绍的是用Python开发,有一篇使用php模拟登录的资料还是在phpcms中实现的,也没有太深入分析. PS:网上资料来源比较乱,不知道php ...

  4. js实现QQ、微信、新浪微博分享功能

    使用js实现QQ.微信.新浪微博分享功能. 微信分享需要手机扫描二维码,需要对url进行编码.在https协议下,扫描二维码时,浏览器打不开可能是没有安全证书导致的. js代码: 1 var shar ...

  5. Java制作一个盒子程序_编写一个简单的Java程序,模拟计算器的功能。

    提问:编写一个简单的Java程序,模拟计算器的功能. 网友回答: 程序参考: import java.awt.*; import java.awt.event.ActionEvent; import ...

  6. 模拟新浪微博随便看看界面布局

    模拟新浪微博随便看看界面布局,布局是利用listview控件,利用adapter使数据和空加你绑定到一起,由于只是为了模仿布局,因此数据是利用List集合设定好的. 布局:布局中标题栏的样式是新建的一 ...

  7. android 分享到微博客户端,Android APP集成新浪微博分享功能

    本文为大家分享了新浪微博分享功能集成,供大家参考,具体内容如下 直接导入weibosdkcore.jar:适用于只需要授权.分享.网络请求框架功能的项目. 无论使用哪一种方式,都需要先将demo中li ...

  8. 模拟斗地主发牌功能的设计与实现

    模拟斗地主发牌功能的设计与实现 参考斗地主的游戏规则,完成一个发牌的功能(54张牌,考虑点数,花色:三名玩家,其中地主比其他玩家多3张牌) 牌类 牌有牌面值.花色及实际大小三个属性 import ja ...

  9. java模拟新浪微博_Java模拟新浪微博用户注册

    模拟新浪微博用户注册 User.java package gather.sina; public class User { private String username; private Strin ...

最新文章

  1. spi协议时序图和四种模式实际应用详解
  2. php因屏幕分辨率显示不一样,分辨率dpi是什么意思
  3. 关于Git下载上传项目的操作指令
  4. 地图投影系列介绍(二)----地理坐标系
  5. [html] link标签的属性media有哪些值?都有什么作用?
  6. Selector#wakeup()
  7. java forkjoin 简书_ForkJoinPool in Java
  8. C语言枚举类型(enum)的各种用法
  9. 通过设置代理解决AndroidStudio无法下载gradle问题
  10. 计算机报名登录服务器超时,登录服务器超时
  11. c# winform 浏览器调用chrome内核
  12. 微型计算机上的tab作用,TAB键有什么用处
  13. 读书笔记:《遇见未知的自己》
  14. 浅谈Android中的Fragment
  15. 美团-移动端UI一致性解决方案
  16. 体验最近火爆的ChatGPT,真的被震惊到了
  17. System Power Tools Suite
  18. 计算机专业研究生面试英语翻译,20考研复试英语面试最强攻略,都是干货!
  19. 3600、宝石与石头
  20. 月均数据_【分析案例】python分析医院销售数据

热门文章

  1. hexo使用jenkins自动部署到阿里云
  2. 面向对象分析和设计(OOA/D)
  3. 1014 装箱问题 CODE[VS]
  4. C++ Primer Plus(十)——对象和类
  5. css基础 设置链接颜色
  6. android 36 线程通信
  7. 3.Chrome数据同步服务分析--server一片
  8. Cent6.5 64位yum安装mysql5.5
  9. 比特币和比特币现金就隐私保护展开辩论
  10. Roger Ver:比特币已经过时,以太坊和比特币现金将实现超越