Django:之BBS项目
首先新建一个BBSProject项目,在建一个app,把app导入到项目中。
在项目BBSProject中的settings.py中,
INSTALLED_APPS = [ \'django.contrib.admin\', \'django.contrib.auth\', \'django.contrib.contenttypes\', \'django.contrib.sessions\', \'django.contrib.messages\', \'django.contrib.staticfiles\', \'app01\',#导入app01 ]
url设置,在BBSProject的urls里导入app01中的views,
from django.conf.urls import url from django.contrib import admin from app01 import views#导入app01中的views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^$\', views.index),#设置默认首页访问页面 ]
在访问index的时候返回的结果是,在app01中的views中设置的index函数。
#_*_coding:utf-8_*_ from django.shortcuts import render,HttpResponse # Create your views here. def index(request): return HttpResponse(u"欢迎访问吴老二博客")
测试简单页面
在做一个bbs之前首先要考虑的是数据库的框架,在一个bbs中需要的内容,还有就是数据库之间的的联用一定要清晰。
注:一个bbs首先要有用户,要有内容,不同的板块,还要有评论,点赞还有就是用户组。
#_*_coding:utf-8_*_ from __future__ import unicode_literals from django.db import models from django.contrib.auth.models import User \'\'\'用户组表,用户组名称不能相同,长度为64,返回用户组名 \'\'\' class UserGroup(models.Model): name = models.CharField(max_length=64,unique=True) def __unicode__(self): return self.name \'\'\'用户信息表,包括用户名,用户组, \'\'\' class UserProfile(models.Model): user = models.OneToOneField(User) name = models.CharField(max_length=32) groups = models.ManyToManyField(UserGroup) def __unicode__(self): return self.name \'\'\' 帖子板块,长度.板块不能重复.用户权限 \'\'\' class Category(models.Model): name = models.CharField(max_length=64,unique=True) admin = models.ManyToManyField(UserProfile) def __unicode__(self): return self.name \'\'\'帖子数据库表,标题,需要设置标题长度,标题不能重复.帖子隶属于板块,帖子插入的图片存储位置,内容以及优先级,帖子内容长度,帖子发布者需要联用用户列表, 如果用户列表在帖子列表下面需要加双引号. \'\'\' class Article(models.Model): title = models.CharField(u"文章标题",max_length=255,unique=True) categroy = models.ForeignKey(Category,verbose_name=u"板块") head_img = models.ImageField(upload_to="uploads") summary = models.CharField(max_length=255) content = models.TextField(u"内容") author = models.ForeignKey(UserProfile) publish_date = models.DateTimeField(auto_now=True) hidden = models.BooleanField(default=True) priority = models.IntegerField(u"优先级",default=1000) def __unicode__(self): return "<%s, author:%s>" %(self.title,self.author) \'\'\' 评论数据库表,评论的帖子需要联用帖子列表,评论者需要调用用户表,评论内容 \'\'\' class Comment(models.Model): article = models.ForeignKey(Article) user = models.ForeignKey(UserProfile) parent_comment = models.ForeignKey(\'self\',related_name=\'p_comment\',blank=True,null=True) comment = models.TextField(max_length=1000) date = models.DateTimeField(auto_now=True) def __unicode__(self): return "<%s, user:%s>" %(self.comment,self.user) \'\'\'点赞表点赞时间,点赞的帖子,和点赞者\'\'\' class ThumbUp(models.Model): article = models.ForeignKey(Article) user = models.ForeignKey(UserProfile) date = models.DateTimeField(auto_now=True) def __unicode__(self): return "<user:%s>" %(self.user)
models
建好数据库需要同步一下:
python manage.py makemigrations python manage.py migrate
开始写页面返回views
#_*_coding:utf-8_*_ from django.shortcuts import render,HttpResponseRedirect import models from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth import authenticate,login,logout from forms import ArticleForm,handle_uploaded_file # Create your views here. def index(request): \'\'\'首页\'\'\' articles = models.Article.objects.all() return render(request,\'index.html\',{\'articles\': articles}) def category(request,category_id): \'\'\'二级分类\'\'\' articles = models.Article.objects.filter(categroy_id=category_id) return render(request,\'index.html\',{\'articles\': articles}) def article_detail(request,article_id): \'\'\'帖子内容\'\'\' try: article_obj = models.Article.objects.get(id=article_id) except ObjectDoesNotExist as e: return render(request,\'404.html\',{\'err_msg\':u"文章不存在!"}) return render(request,\'article.html\', {\'article_obj\':article_obj}) def acc_logout(request): \'\'\'退出登陆\'\'\' logout(request) return HttpResponseRedirect(\'/\') def acc_login(request): \'\'\'登陆\'\'\' print(request.POST) err_msg =\'\' if request.method == "POST": print(\'user authention...\') username = request.POST.get(\'username\') password = request.POST.get(\'password\') user = authenticate(username=username,password=password) if user is not None: login(request,user) return HttpResponseRedirect(\'/\') else: err_msg = "Wrong username or password!" return render(request,\'login.html\',{\'err_msg\':err_msg}) def new_article(request): \'\'\'最新帖子\'\'\' if request.method == \'POST\': print(request.POST) form = ArticleForm(request.POST,request.FILES) if form.is_valid(): print("--form data:",form.cleaned_data) form_data = form.cleaned_data form_data[\'author_id\'] = request.user.userprofile.id new_img_path = handle_uploaded_file(request,request.FILES[\'head_img\']) form_data[\'head_img\'] = new_img_path new_article_obj = models.Article(**form_data) new_article_obj.save() return render(request,\'new_article.html\',{\'new_article_obj\':new_article_obj}) else: print(\'err:\',form.errors) category_list = models.Category.objects.all() return render(request,\'new_article.html\', {\'categroy_list\':category_list})
views
路径urls
#_*_coding:utf-8_*_ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^$\',views.index, name="index" ), url(r\'^category/(\d+)/$\',views.category,name="category" ), url(r\'^article/(\d+)/$\',views.article_detail,name="article_detail"), url(r\'^article/new/$\',views.new_article,name="new_article"), url(r\'account/logout/\',views.acc_logout,name=\'logout\'), url(r\'account/login/\',views.acc_login,name=\'login\'), ]
可以登陆管理员后台建立板块和用户,发布帖子,帖子存放路径需要新建一个forms在app01里。
#!/usr/bin/env python # -*- coding:utf-8 -*- from django import forms import os class ArticleForm(forms.Form): \'\'\'帖子路径包括标题,内容作者,图片\'\'\' title = forms.CharField(max_length=255,min_length=5) summary = forms.CharField(max_length=255,min_length=5) categroy_id = forms.IntegerField() head_img = forms.ImageField() content = forms.CharField(min_length=10) def handle_uploaded_file(request,f): \'\'\'帖子图片存储路径\'\'\' base_img_upload_path = \'statics/imgs\' user_path = "%s/%s" %(base_img_upload_path,request.user.userprofile.id) if not os.path.exists(user_path): os.mkdir(user_path) with open("%s/%s" %(user_path,f.name), \'wb+\') as destination: for chunk in f.chunks(): destination.write(chunk) return "/static/imgs/%s/%s" %(request.user.userprofile.id,f.name)
关于帖子的评论需要考虑级别,在app01里新建一个tree_search_test评论函数。
#!/usr/bin/env python # -*- coding:utf-8 -*- \'\'\'评论\'\'\' data = [ (None,\'A\'), (\'A\',\'A1\'), (\'A\',\'A1-1\'), (\'A1\',\'A2\'), (\'A1-1\',\'A2-3\'), (\'A2-3\',\'A3-4\'), (\'A1\',\'A2-2\'), (\'A2\',\'A3\'), (\'A2-2\',\'A3-3\'), (\'A3\',\'A4\'), (None,\'B\'), (\'B\',\'B1\'), (\'B1\',\'B2\'), (\'B1\',\'B2-2\'), (\'B2\',\'B3\'), (None,\'C\'), (\'C\',\'C1\'), ] def tree_search(d_dic,parent,son): for k,v_dic in d_dic.items(): if k == parent: #find your parent d_dic[k][son] = {} print("find parent of :", son) return else: # might in the deeper layer print("going to furhter layer...") tree_search(d_dic[k],parent,son) data_dic = {} for item in data: parent,son = item if parent is None:# has no parent data_dic[son] ={} else: # looking for its parent tree_search(data_dic,parent,son) for k,v in data_dic.items(): print(k,v ) \'\'\' data_dic = { \'A\': { \'A1\': { \'A2\':{ \'A3\':{ \'A4\':{} } }, \'A2-2\':{ \'A3-3\':{} } } }, \'B\':{ \'B1\':{ \'B2\':{ \'B3\':{} }, \'B2-2\':{} } }, \'C\':{ \'C1\':{} } }\'\'\'
tree_search_test
一下是前台页面的处理,首先要设置语言和路径,在settings里设置。
LANGUAGE_CODE = \'en-us\' TIME_ZONE = \'UTC\' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto/static-files/ STATIC_URL = \'/static/\' STATIC_URL = \'/static/\' STATICFILES_DIRS = ( "%s/%s" %(BASE_DIR, "statics"), # "%s/%s" %(BASE_DIR, ""), #static/uploads/uploads/ )
html文件可以在下面下载。
index的导航部分
<div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li ><a href="{% url \'index\' %}">综合区</a></li> <li><a href="{% url \'category\' 1 %}">欧美专区</a></li> <li><a href="{% url \'category\' 2 %}">日韩专区</a></li> <li><a href="{% url \'category\' 3 %}">河北专区</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.is_authenticated %} <li class="dropdown"> <a href="http://v3.bootcss.com/examples/navbar-fixed-top/#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{ request.user.userprofile.name }} <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="{% url \'new_article\' %}">发贴</a></li> <li><a href="http://v3.bootcss.com/examples/navbar-fixed-top/#">Another action</a></li> <li><a href="http://v3.bootcss.com/examples/navbar-fixed-top/#">Something else here</a></li> <li role="separator" class="divider"></li> <li class="dropdown-header">Nav header</li> <li><a href="http://v3.bootcss.com/examples/navbar-fixed-top/#">Separated link</a></li> <li><a href="{% url \'logout\' %}">注销</a></li> </ul> </li> {% else %} <li><a href="{% url \'login\'%}">注册\登录</a></li> {% endif %} </ul> </div>
导航下分帖子展示和其他板块
<div class="container"> {% block page-container %} <div class="row"> <div class="col-md-8 left-content-panel"> <div class="content-box"> {% for article in articles reversed %} <div class="article-box row"> <div class="article-head-img col-md-3"> <img src="{{ article.head_img }}"> </div> <div class="article-summary col-md-8"> <h4><a href="{% url \'article_detail\' article.id %}">{{ article.title }}</a></h4> <div class="article-attr"> <ul class="list-inline"> <li>{{ article.author.name }}</li> <li>{{ article.publish_date }}</li> <li>thumbup:{{ article.thumbup_set.select_related.count }}</li> <li>comments:{{ article.comment_set.select_related.count }}</li> </ul> </div> <p>{{ article.summary }}</p> </div> </div> <hr > {% endfor %} </div> </div> <div class="col-md-4 right-sidebar"> bar </div> </div> {% endblock %} </div>
js的调用
<script src="/static/bootstrap/js/jquery-2.1.4.js"></script> <script src="/static/bootstrap/js/bootstrap.min.js"></script> <!-- IE10 viewport hack for Surface/desktop Windows 8 bug --> <script src="/static/bootstrap/js/ie10-viewport-bug-workaround.js"></script> <script type="text/javascript"> $(document).ready(function(){ var menus = $("#navbar a[href=\'{{ request.path }}\']")[0]; $(menus).parent().addClass("active"); $(menus).parent().siblings().removeClass("active"); //console.log(menus); }); </script> {% block bottom-js %} {% endblock %}
登陆页面
{% extends \'index.html\' %} {% block page-container %} <div class="col-md-4"> <form class="form-signin" action="{% url \'login\' %}" method="post">{% csrf_token %} <h2 class="form-signin-heading">Please sign in</h2> <label for="inputEmail" class="sr-only">用户名</label> <input type="text" id="" name="username" class="form-control" placeholder="username" required="" autofocus=""> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required=""> <div class="checkbox"> <label> <input type="checkbox" value="remember-me"> Remember me </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> <p style="color:red;">{{ err_msg }}</p> </form> </div> {% endblock %}
最新帖子
{% extends \'index.html\' %} {% block head-js %} <script src="/static/plugins/ckeditor/ckeditor.js"></script> {% endblock %} {% block page-container %} <div class="new-article"> {% if new_article_obj %} <h3>文章<{{ new_article_obj.title }}>已发布,<a href="{% url \'article_detail\' new_article_obj.id %}"> 点我查看</a></h3> {% else %} <form enctype="multipart/form-data" method="post" action="{% url \'new_article\' %}">{% csrf_token %} <input name="title" type="text" class="form-control" placeholder="文章标题"> <select name="categroy_id" class="form-control"> {% for category in categroy_list %} <option value="{{ category.id }}">{{ category.name }}</option> {% endfor %} </select> <input name="summary" type="text" class="form-control" placeholder="一句话文章中心思想..."> <input type="file" name="head_img">必选文章标题图片 <textarea id="ck-editor" name="content" class="form-control" rows="3"></textarea> <br/> <button type="submit" class="btn btn-success pull-right">发贴</button> </form> {% endif %} </div> {% endblock %} {% block bottom-js %} <script> CKEDITOR.replace( \'ck-editor\' ); CKEDITOR.editorConfig = function( config ) { //config.language = \'es\'; config.uiColor = \'#F7B42C\'; config.height = 500; config.toolbarCanCollapse = true; }; </script> {% endblock %}
所有帖子
{% extends \'index.html\' %} {% load custom_tags %} {% block page-container %} <div class="article-detail"> <h4>{{ article_obj.title }}</h4> <p>{{ article_obj.content|safe }}</p> <hr/> {% build_comment_tree article_obj.comment_set.select_related %} </div> {% endblock %}
报错404
{% extends \'index.html\' %} {% block page-container %} <h1 style="font-size: 200px">404</h1> <h3>{{ err_msg }}</h3> {% endblock %}
以上是一个简单的bbs的搭建和制作,参考文件
webqq聊天室
webqq聊天室就给予上面的bbs制作吧,首先是数据库
在app01的数据库的用户信息表中新建朋友表。
class UserProfile(models.Model): \'\'\' 用户信息表,包括用户名,用户组, \'\'\' user = models.OneToOneField(User) name = models.CharField(max_length=32) groups = models.ManyToManyField(\'UserGroup\') friends = models.ManyToManyField(\'self\', related_name=\'my_friends\')#新加的朋友表 def __unicode__(self): return self.name
新建一个webqq项目,数据库中新建聊天组。
from __future__ import unicode_literals from django.db import models from app01.models import UserProfile # Create your models here. class QQGroup(models.Model): name = models.CharField(max_length=64,unique=True) description = models.CharField(max_length=255,default="nothing...") members = models.ManyToManyField(UserProfile,blank=True) admins = models.ManyToManyField(UserProfile,related_name=\'group_admins\') max_member_nums = models.IntegerField(default=200) def __unicode__(self): return self.name
聊天组的views
#_*_coding:utf-8_*_ from django.shortcuts import render,HttpResponse from webqq import models import json,Queue,time from django.contrib.auth.decorators import login_required#登录判断 # Create your views here. GLOBAL_MQ = {} @login_required def dashboard(request): return render(request,\'webqq/dashboard.html\') \'\'\'聊天页面函数返回聊天页面 \'\'\' @login_required def contacts(request): contact_dic = { #\'contact_list\': [], #\'group_list\': [], } contacts = request.user.userprofile.friends.select_related().values(\'id\',\'name\') contact_dic[\'contact_list\']= list(contacts) groups = request.user.userprofile.qqgroup_set.select_related().values("id",\'name\',\'max_member_nums\') contact_dic[\'group_list\'] = list(groups) print(contact_dic) return HttpResponse(json.dumps(contact_dic)) \'\'\'好有聊天,以及群组聊天 \'\'\' @login_required def new_msg(request): if request.method == \'POST\': print(\'-->\',request.POST.get(\'data\')) data = json.loads(request.POST.get(\'data\')) send_to = data[\'to\'] msg_from = data["from"] contact_type = data[\'contact_type\'] data[\'timestamp\'] = time.time() if contact_type == \'group_contact\': group_obj = models.QQGroup.objects.get(id=send_to) for member in group_obj.members.select_related(): if str(member.id) not in GLOBAL_MQ: GLOBAL_MQ[str(member.id)] = Queue.Queue() if str(member.id) != msg_from: GLOBAL_MQ[str(member.id)].put(data) else: if send_to not in GLOBAL_MQ: GLOBAL_MQ[send_to] = Queue.Queue() GLOBAL_MQ[send_to].put(data) return HttpResponse(GLOBAL_MQ[send_to].qsize()) else:#recv msgs request_user = str(request.user.userprofile.id) msg_lists = [] print(GLOBAL_MQ,request_user) if request_user in GLOBAL_MQ: print("hehe") stored_msg_nums = GLOBAL_MQ[request_user].qsize() if stored_msg_nums ==0: #no new msgs try: print("\033[41;1mNo new msg , wait for 60 secs...\033[0m") msg_lists.append(GLOBAL_MQ[request_user].get(timeout=15)) except Exception as e: print("err:",e) print("\033[41;1mtime out or new msgs....\033[0m ") for i in range(stored_msg_nums): msg_lists.append(GLOBAL_MQ[request_user].get()) else: #create a new queue for this user GLOBAL_MQ[str(request.user.userprofile.id)] = Queue.Queue() return HttpResponse(json.dumps(msg_lists)) \'\'\'聊天消息发送,首先是判断是群组聊天还是个人聊天,群组聊天直接进去群组,个人聊天直接返回个人,根据不同的聊天对象发送消息,并且返回 \'\'\'
webqq.Views
BBSProject项目的url把webqq的url导入进去进去。
from django.conf.urls import url,include from django.contrib import admin from app01 import views from webqq import urls as char_urls urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^chat/\', include(char_urls)),#webqq的url url(r\'^$\',views.index, name="index" ), url(r\'^category/(\d+)/$\',views.category,name="category" ), url(r\'^article/(\d+)/$\',views.article_detail,name="article_detail"), url(r\'^article/new/$\',views.new_article,name="new_article"), url(r\'account/logout/\',views.acc_logout,name=\'logout\'), url(r\'account/login/\',views.acc_login,name=\'login\'), ]
webqq下新建一个url
from django.conf.urls import include, url import views urlpatterns = [ url(r\'dashboard/$\',views.dashboard,name=\'webqq\'), url(r\'contacts/$\',views.contacts,name=\'load_contact_list\'), url(r\'msg/$\',views.new_msg,name=\'send_msg\'), url(r\'msg/$\',views.new_msg,name=\'get_new_msgs\'), ]
webqq下的tests信息
from django.test import TestCase # Create your tests here. def callMyself(n): print("level:",n ) callMyself(n+1) print(\'111\') return 0 callMyself(1)
webqq下的admin
from django.contrib import admin from webqq import models # Register your models here. admin.site.register(models.QQGroup)
webqq下的apps
from __future__ import unicode_literals from django.apps import AppConfig class WebqqConfig(AppConfig): name = \'webqq\'
后台信息建好开始更新数据库
python manage.py makemigrations python manage.py migrate
把前台的web数据编辑
{% extends \'index.html\' %} {% block page-container %} {% csrf_token %} <h1>好基友聊天室</h1> <div> <!-- Nav tabs --> <ul class="nav nav-tabs" role="tablist"> <li role="presentation" chat-type="contact_list" contact-type="single_contact" class="active"><a href="#contacts"role="tab" data-toggle="tab">联系人</a></li> <li role="presentation" chat-type="group_list" contact-type="group_contact"><a onclick="LoadContacts();" href="#contacts" role="tab" data-toggle="tab">群组</a></li> <li role="presentation"><a href="#notifications" role="tab" data-toggle="tab">通知</a></li> <li role="presentation"><a href="#settings" role="tab" data-toggle="tab">配置</a></li> </ul> <!-- Tab panes --> <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="contacts" > <div class="chat-container row"> <div class="contact-list col-md-3"> <div class="list-group"> </div> </div> <div class="chat-box col-md-9"> <div class="chat-header"> </div> <div class="chat-content"> content</div> <div class="chat-msg-sendbox"> <div class="msg-box col-md-10"> <textarea></textarea> </div> <div class="msg-box-btn col-md-2"> <button type="button" class="btn btn-success">发送</button> </div> </div> </div> </div> </div> <div role="tabpanel" class="tab-pane" id="groups">profile...</div> <div role="tabpanel" class="tab-pane" id="notifications">...</div> <div role="tabpanel" class="tab-pane" id="settings">...</div> </div> </div> {% endblock %} {% block bottom-js %} <script> //csrf ref function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie != \'\') { var cookies = document.cookie.split(\';\'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) == (name + \'=\')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie(\'csrftoken\'); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } }); //end csrf ref $(document).ready(function(){ //load all contacts GLOBAL_SESSION_CACHE = { \'single_contact\':{}, \'group_contact\':{} } LoadContacts(); //var RefreshNewMsgs = setInterval(function(){ GetNewMsgs(); //},31000); //send msg $("body").delegate("textarea", "keydown",function(e){ if(e.which == 13) {//Enter key down //send msg button clicked var msg_text = $("textarea").val(); if ($.trim(msg_text).length > 0){ console.log(msg_text); SendMsg(msg_text); } //no wait the send_msg\'s call confirm msg AddSentMsgIntoChatBox(msg_text); $("textarea").val(\'\'); } });//end body });//end doc ready function AddRecvMsgToChatBox(msg_item){ var msg_ele = "<div class=\'msg-item-recv\'>" + "<p>" + msg_item.from_name + " " + msg_item[\'timestamp\'] + "</p>" + "<p>" + msg_item.msg + "</p>" + "</div>"; $(".chat-content").append(msg_ele); $(\'.chat-content\').animate({ scrollTop: $(\'.chat-content\')[0].scrollHeight}, 500 );//e } function GenerateNewMsgItem(msg_item){ var msg_ele = "<div class=\'msg-item-recv\'>" + "<p>" + msg_item.from_name + " " + msg_item[\'timestamp\'] + "</p>" + "<p>" + msg_item.msg + "</p>" + "</div>"; return msg_ele; } function AddSentMsgIntoChatBox(msg_text){ var d = new Date(); var send_time = d.getHours() + ":"+ d.getMinutes() + ":"+ d.getSeconds(); var msg_ele = "<div class=\'msg-item-sent\'>" + "<p>" + "{{ request.user.userprofile.name }} " + send_time + "</p>" + "<p>" + msg_text + "</p>" + "</div>"; $(".chat-content").append(msg_ele); $(\'.chat-content\').animate({ scrollTop: $(\'.chat-content\')[0].scrollHeight}, 500 );//e } function LoadContacts(){ $.get("{% url \'load_contact_list\' %}", function(callback){ console.log(callback); var data = JSON.parse(callback); var current_tab = $(".nav-tabs li").filter(".active")[0]; var chat_type = $(current_tab).attr("chat-type"); var contact_type = $(current_tab).attr("contact-type"); $(".contact-list .list-group").empty(); $.each(data[chat_type], function(index, ele){ var ele = "<a href=\'#\' onclick=\'OpenDialogBox(this);\' class=\'list-group-item\' contact_id=\'"+ ele.id +"\' contact_type=\'"+contact_type +"\' >" + ele.name + "<span class=\'badge\'>0</span></a>"; $(".contact-list .list-group").append(ele); });//end each });//end get } function GetCsrfToken(){ return $("input[name=\'csrfmiddlewaretoken\']").val(); } function OpenDialogBox(ele){ var contact_id = $(ele).attr("contact_id"); var contact_type = $(ele).attr("contact_type"); var contact_name = $(ele).text(); //dump current session contents DumpSession(); var new_header = "<h4><span contact_id=\'" + contact_id + "\'" + "contact_type=\'"+ contact_type+"\'>Talking with " + contact_name + "</span></h4>"; $(".chat-header").html(new_header); $(".chat-content").html(LoadSession(contact_id,contact_type)); //clear the unread msg num flags var unread_msg_num_ele = $(ele).find("span")[0]; $(unread_msg_num_ele).text(0); $(unread_msg_num_ele).css("display","none"); } function DumpSession(){ var current_contact_id = $(".chat-header span").attr("contact_id"); var current_contact_type= $(".chat-header span").attr("contact_type"); //console.log($(".chat-content").html()); console.log("contact id:::" +current_contact_id ); if (current_contact_id){ GLOBAL_SESSION_CACHE[current_contact_type][current_contact_id] =$(".chat-content").html(); } } function DumpSession2(contact_id,contact_type,content){ if (contact_id){ GLOBAL_SESSION_CACHE[contact_type][contact_id] =content; } } function LoadSession(contact_id,contact_type){ if (GLOBAL_SESSION_CACHE[contact_type].hasOwnProperty(contact_id) ){ var session_html = GLOBAL_SESSION_CACHE[contact_type][contact_id]; }else{ var session_html = \'\'; } return session_html; //$(".chat-content").html(session_html); } function SendMsg(msg_text){ var contact_id = $(".chat-header span").attr("contact_id"); console.log("contact_id" + contact_id); var contact_type = $(".chat-header span").attr("contact_type"); var msg_dic = { \'contact_type\':contact_type, \'to\':contact_id, \'from\': "{{ request.user.userprofile.id }}", \'from_name\':"{{ request.user.userprofile.name }}", \'msg\':msg_text } //$.post("{% url \'send_msg\' %}",{\'data\':JSON.stringify(msg_dic),\'csrfmiddlewaretoken\':GetCsrfToken()}, function(callback){ $.post("{% url \'send_msg\' %}",{\'data\':JSON.stringify(msg_dic)}, function(callback){ console.log(callback); });//end post } function GetNewMsgs(){ $.get("{% url \'get_new_msgs\' %}",function(callback){ console.log("new msgs:" + callback); var msg_list = JSON.parse(callback); var current_open_session_id = $(".chat-header span").attr("contact_id"); var current_open_session_type = $(".chat-header span").attr("contact_type"); $.each(msg_list, function(index,msg_item){ if (msg_item.contact_type == \'single_contact\'){ if (msg_item.contact_type == current_open_session_type){ if(msg_item.from == current_open_session_id){ AddRecvMsgToChatBox(msg_item); }else{ // 代表这个session当前未被打开 var old_session_content = LoadSession(msg_item.from,msg_item.contact_type); var new_msg_ele = GenerateNewMsgItem(msg_item); var new_session_content =old_session_content+ new_msg_ele; DumpSession2(msg_item.from ,msg_item.contact_type,new_session_content) UpdateUnreadMsgNums(msg_item.from ,msg_item.contact_type); };//end if(msg_item.from == current_open_session_id) };//end if msg_item.contact_type == current_open_session_type }else{//for single contact if (msg_item.contact_type == current_open_session_type){ if (msg_item.to == current_open_session_id){ //current group dialog is opened... AddRecvMsgToChatBox(msg_item); }else{ var old_session_content = LoadSession(msg_item.to,msg_item.contact_type); var new_msg_ele = GenerateNewMsgItem(msg_item); var new_session_content =old_session_content+ new_msg_ele; DumpSession2(msg_item.to ,msg_item.contact_type,new_session_content); UpdateUnreadMsgNums(msg_item.to ,msg_item.contact_type); } } };// for group contact });//end each //start a new request again console.log("----run again...."); GetNewMsgs(); });//end get } function UpdateUnreadMsgNums(contact_id ,contact_type){ var msg_num_ele = $(".contact-list a[contact_id=\'" + contact_id +"\']").find("span")[0]; $(msg_num_ele).text( parseInt($(msg_num_ele).text()) + 1); $(msg_num_ele).show(); } </script> {% endblock %}
webqq聊天室制作完毕,有些功能还不太完善,但是给予聊天已经没有问题,