zoukankan      html  css  js  c++  java
  • 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("33[41;1mNo new msg , wait for 60 secs...33[0m")
                        msg_lists.append(GLOBAL_MQ[request_user].get(timeout=15))
                    except Exception as e:
                        print("err:",e)
                        print("33[41;1mtime out or new msgs....33[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聊天室制作完毕,有些功能还不太完善,但是给予聊天已经没有问题,  

     

  • 相关阅读:
    Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
    Spring Boot 如何给微信公众号返回消息
    Spring Boot2 系列教程(十九)Spring Boot 整合 JdbcTemplate
    Spring Boot2 系列教程(十八)Spring Boot 中自定义 SpringMVC 配置
    Spring Boot 开发微信公众号后台
    Spring Boot2 系列教程(十七)SpringBoot 整合 Swagger2
    Spring Boot2 系列教程(十六)定时任务的两种实现方式
    Spring Boot2 系列教程(十五)定义系统启动任务的两种方式
    Spring Boot2 系列教程(十四)CORS 解决跨域问题
    JavaScript二维数组
  • 原文地址:https://www.cnblogs.com/wulaoer/p/5343105.html
Copyright © 2011-2022 走看看