Django:之BBS項目

首先新建一個BBSProject項目,在建一個app,把app導入到項目中。javascript

在項目BBSProject中的settings.py中,css

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,html

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函數。java

#_*_coding:utf-8_*_
from django.shortcuts import render,HttpResponse

# Create your views here.
def index(request):
    return HttpResponse(u"歡迎訪問吳老二博客")

測試簡單頁面python

在作一個bbs以前首先要考慮的是數據庫的框架,在一個bbs中須要的內容,還有就是數據庫之間的的聯用必定要清晰。jquery

注:一個bbs首先要有用戶,要有內容,不一樣的板塊,還要有評論,點贊還有就是用戶組。web

#_*_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

建好數據庫須要同步一下:ajax

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

路徑urlsdjango

#_*_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聊天室製做完畢,有些功能還不太完善,可是給予聊天已經沒有問題,  

相關文章
相關標籤/搜索