首先新建一个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聊天室制作完毕,有些功能还不太完善,但是给予聊天已经没有问题,  

 

版权声明:本文为wulaoer原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/wulaoer/p/5343105.html