Python学习day14 BBS功能和聊天室

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习day14 BBS功能和聊天室相关的知识,希望对你有一定的参考价值。

Created on 2017年5月15日 @author: louts


第1课 作业讲解及装饰器使用 28minutes


def check(func):
def rec(request,*args,**kargs):
return func(request,*args,**kargs)
return rec

@check
def index(request,):
print request

第2课 自定义装饰器扩展使用 18minutes

第3课

第4课 BBS功能分析及介绍 37minutes
分析网站的架构
自己写数据库Models
参考网站的前端来写一个页面
这节完成了页面头部的代码

第5课 BBS功能之点赞 40minutes
按HTML分几个部分
页头,内容,页尾
内容中按标题,内容,通过迭代数据库内容显示出来
参考页面写CSS和jQuery
可以在函数中定义好几个参数
item是数据的一条记录
<a href=‘‘ onclick=‘Favor(this,{{item.id}})‘>点赞{{item.favor_count}}</a>

<script type=‘text/javascript‘>
//jquery还是有错误,无法正常使用20170517
function Favor(doc,id){
$.ajax({
//注意Ajax里不能用冒号,要用逗号
url:‘/addfavor/‘,
data:{id:id},
type:‘POST‘,
sussess:function(arg){
console.log(arg);
var temp = ‘赞‘ + arg;
$(doc).text(temp);
}
})

2017/05/22
第6课 BBS功能之评论一 53minutes

思路:
点击 评论,触发Reply,Reyly去找父标签的下一个兄弟标签的第一个标签,对这个标签操作---目前这里实际操作失败
在这个标签下,定义输入框,和历史记录(记录用Ajax到数据库里取),对这个标签初始CSS为display:None

可以在这个标签里设定两个CSS,用于区别后台数据和当前输入框,找到历史的CSS,对这个标签做添加

前端:
-----------------------------------------------------------------------------------
<div class=‘part3‘>
<a href=‘‘ onclick=‘Favor(this,{{item.id}})‘>点赞{{item.favor_count}}</a>
<a href=‘‘ id=‘id1‘ onclick=‘Reply()‘>评论{{item.reply_count}}</a>
<span>{{item.create_date|date:‘Y-m-d H:i:s‘}}</span>
</div>
<!-- 下面自定义一个属性has-input用于JAVA里的判断是否有穿入框了 -->
<div has-input=0 class=‘part4 hide‘>
<!--这底下两个CSS用于下面Java的处理 -->
<div class=‘replys‘></div>
<div class=‘input‘>
<lable>请输入内容:</lable>
<textarea></textarea>
<input type=‘button‘ value=‘提交‘>
</div>
</div>

function Reply(doc,id){
$.ajax(){
url:‘/getreply/‘,
type:‘POST‘,
data:{nid,id},
sussess:function(callback){
//callback是后台返回的数据
console.log(callback;)
var obj = jQuery.parseJSON(callback);
$.each(obj,function(k,v){
//当前标签和父亲标签的下一个标签的第一个标签
//$(doc).parent().next().first().text(‘0000‘)
var temp = ‘<p>‘ + v.fields.content + ‘</p>‘;
//这里找到.reply的CSS,先清除当前的内容,不然会出现重复
$(doc).parent().next().find(‘.replys‘).empty();
//这里找到.reply的CSS,再将返回的数据插进去
$(doc).parent().next().find(‘.replys‘).append(temp);
});
//这里点击时会去掉当前的hide的CSS
$(doc).parent().next().toggleClass(‘hide‘);
}
}
//console.log($(‘#content‘).attr(‘has-input‘));
//$(‘#rid‘).removeClass(‘part4‘);
//toggleClass反复的加减CSS
//$(‘#content‘).toggleClass(‘hide‘);
var html = $(‘#id1‘).parent().next().first()
console.log(html)
//removeClass(‘hide‘);
}



后端:
-----------------------------------------------------------------------------------
def getreply(request):
id = request.POST.get(‘nic‘)
#这里可直接用外键__字段获取另一张表的内容 user__username new__id
reply_list = Reply.objcects.filter(new__id=id).values(‘id‘,‘content‘,‘user__username‘,‘create_date‘)

#json 无法序列化一个时间,可用serializers来操作
#serialize(format, queryset, **options)
reply_list = serializers.serialize(‘json‘, reply_list)
return HttpResponse(reply_list)

2017/05/24
第7课 BBS功能之评论二 55minutes


#用于Jason序列化时间格式
class CJsonEncoder(json.JSONEncoder):
def default(self,obj):
if isinstance(obj,datetime.datetime):
return obj.strftime(‘%Y-%m-%d %H:%M:%S‘)
elif isinstance(obj,date):
return obj.strftime(‘%Y-%m-%d‘)
else:
return json,JSONEncoder.default(self,obj)

def getreply(request):
id = request.POST.get(‘nic‘)
#这里可直接用外键__字段获取另一张表的内容 user__username new__id
reply_list = Reply.objcects.filter(new__id=id).values(‘id‘,‘content‘,‘user__username‘,‘create_date‘)

#json 无法序列化一个时间,可用serializers来操作
#serialize(format, queryset, **options)
‘‘‘
reply_list = serializers.serialize(‘json‘, reply_list)
return HttpResponse(reply_list)
‘‘‘
#用自己定义的类来处理时间格式
reply_list = list(reply_list)
json.dumps(reply_list,cls=CJsonEncoder)
return HttpResponse(reply_list)


提交评论,实时在页面上显示提交的内容(需提交到数据库中),同时自动更新评论的数量(也要更新数据库,并将数量返回给前台)
前端:
-----------------------------------------------------------------------------------
<div class=‘part3‘>
<a href=‘‘ onclick=‘Favor(this,{{item.id}})‘>点赞{{item.favor_count}}</a>
<a href=‘‘ class=‘reply‘ onclick=‘Reply(this,{{item.id}})‘>评论{{item.reply_count}}</a>
<span>{{item.create_date|date:‘Y-m-d H:i:s‘}}</span>
</div>
<!-- 下面自定义一个属性has-input用于JAVA里的判断是否有穿入框了 -->
<div has-input=0 class=‘part4 hide‘>
<!--这底下两个CSS用于下面Java的处理 -->
<div class=‘replys‘></div>
<div class=‘input‘>
<lable>请输入内容:</lable>
<textarea></textarea>
<!-- 这里添加item.id,是提交的时候要关联到这个新闻,不能放到其他的新闻里去
这里的this,一样通过此标签的上一个标签,就是提交的内容 -->
<input type=‘button‘ value=‘提交‘ onclick=‘Submit(this,{{item.id}})‘>
</div>
</div>

{% endfor %}
</div>


<!-- 遮罩层开始 -->
<div id=‘shade‘ class=‘shade hide‘></div>
<!-- 遮罩层结束 -->
<!-- 加载层开始 -->
<div id=‘loading‘ class=‘loading hide‘></div>
<!-- 加载层结束 -->


function Submit(doc,id){
//上一个标签
var value = $(doc).prev().val();
//提交后清除输入框
$(doc).prev().val(‘‘);
$(‘#shade,loading‘).removeClass(‘hide‘);
$.ajax(){
url:‘/submitreply/‘,
type:‘POST‘,
data:{nid:id,data:value},
sussess:function(callback){
//callback是后台返回的数据
console.log(callback;)
var callback = jQuery.parseJSON(callback);
if (callback.status==1){
//把数据Append到回复列表中
temp = ‘<p>‘ + callback.data.username + ‘:‘ + callback.data.content + ‘---‘ + callback.data.create_date + ‘</p>‘;
$(doc).parent().prev().append(temp)

//底下两行代码可以让评论数实时的更新,添加一条时自动计数
//先提交到后台,正常保存后自动加1,同时将新的内容和数值提交到前台
count = ‘评论‘ + callback.data.reply_count
$(doc).parent().parent().prev().find(‘.reply‘).text(count)
}else{
alert(‘失败‘)}
}
$(‘#shade,loading‘).addClass(‘hide‘);
}
}


后端:
-----------------------------------------------------------------------------------

def submitreply(request):
ret = {‘status‘:0,‘data‘:‘‘,‘message‘:‘‘}
try:
id = request.POST.get(‘nid‘)
data = request.POST.get(‘data‘)
#获取新闻的对象
newsObj = News.objects.get(id=id)
obj = Reply.objects.create(content=data,
user=Admin.objects.get(id=request.session[‘current_user_id‘]),
new=newsObj)
#评论保存后同时要更新闻的评论条目,自动加1
temp = newsObj.reply_count + 1
newsObj.reply_count = temp
newsObj.save()
#将数量放到前端的字典中
ret[‘data‘]= {‘reply_count‘:temp,‘content‘:obj.content,
‘user__name‘:obj.user.username,
‘create_date‘:obj.create_date.strftime(‘%Y-%m-%d %H:%M:%S‘)}
ret[‘status‘] = 1
except Exception,e:
ret[‘message‘] = e.message


return HttpResponse(json.dumps(ret))


后台

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render,render_to_response,HttpResponse, redirect
from models import *
import json
from django.core import serializers
from json.encoder import JSONEncoder
from django.contrib.redirects.models import Redirect

# Create your views here.

def index(request):
    all_data = News.objects.all()
    return render_to_response(‘index.html‘,{‘data‘:all_data})



#用于点赞功能,点击时写到数据库中,并将数据返回给前台
def addfavor(request):
    ret = {‘status‘:0,‘data‘:‘‘,‘message‘:‘‘}
    try:
        #这块有时会出现Sock错误error: [Errno 10053]
        id = request.POST.get(‘id‘)
        newsObj = News.objects.get(id=id)
        temp = newsObj.favor_count + 1
        newsObj.favor_count = temp
        newsObj.save()
        ret[‘status‘] = 1
        ret[‘data‘] = temp
    except Exception,e:
        print ‘error‘
        ret[‘message‘] = ‘页面出错了‘
        print  ret[‘message‘] 
    return HttpResponse(json.dumps(ret))


‘‘‘
#外键取数据可以用外键名称__id来操作,查询用点
#如果数据中有时间格式,Json无法序列化
#可使用Django的专用包来解决 serializers
#serializers.serialize(format, queryset)

#不能通过Reply(‘#reply_detail来访问Part4的内容,这样点击后会改变所有
#要通过子标签的父标签的下一个标签来找到$(doc).parent().netx()
$(doc).parent().next().first()找到子类第一个标签,可用Appen添加内容,
或ToggleClass来去掉CSS

Jquery用来迭代数据,obj是一个序列 
$.each(obj,function(k,v){
            temp = v.fields
            })
‘‘‘
#用于Jason序列化时间格式
class CJsonEncoder(json.JSONEncoder):
    def default(self,obj):
        if isinstance(obj,datetime.datetime):
            return obj.strftime(‘%Y-%m-%d %H:%M:%S‘)
        elif isinstance(obj,date):
            return obj.strftime(‘%Y-%m-%d‘)
        else:
            return json,JSONEncoder.default(self,obj)
        
#用于前台点击评论时显示当前新闻的评论内容       
def getreply(request):
    id = request.POST.get(‘nic‘)
    #这里可直接用外键__字段获取另一张表的内容 user__username  new__id
    reply_list = Reply.objcects.filter(new__id=id).values(‘id‘,‘content‘,‘user__username‘,‘create_date‘)
    
    #json 无法序列化一个时间,可用serializers来操作
    #serialize(format, queryset, **options)
    ‘‘‘
    reply_list = serializers.serialize(‘json‘, reply_list)
    return HttpResponse(reply_list)
    ‘‘‘
    #用自己定义的类来处理时间格式
    reply_list = list(reply_list)
    json.dumps(reply_list,cls=CJsonEncoder)
    return HttpResponse(reply_list)
    

#用于前台提供评论内容


def login(request):
    if request.methos == ‘POST‘:
        username = request.POST.get(‘usernmae‘)
        password = request.POST.get(‘password‘)
        try:
            #currentObj得到是一个对象
            currentObj = Admin.objects.get(username=username,
                                     passsword=password)
        except Exception,e:
            currentObj = None
        if currentObj:
            request.session[‘current_user_id‘] = currentObj.id
            return redirect(‘/index‘)
        else:
            return redirect(‘/login‘)
        
    return render_to_response(‘login.html‘)                    

def submitreply(request):
    ret = {‘status‘:0,‘data‘:‘‘,‘message‘:‘‘}
    try:
        id = request.POST.get(‘nid‘)
        data = request.POST.get(‘data‘)
        #获取新闻的对象
        newsObj = News.objects.get(id=id)
        obj = Reply.objects.create(content=data,
                             user=Admin.objects.get(id=request.session[‘current_user_id‘]),
                             new=newsObj)
        #评论保存后同时要更新闻的评论条目,自动加1
        temp = newsObj.reply_count + 1
        newsObj.reply_count = temp
        newsObj.save()
        #将数量放到前端的字典中
        ret[‘data‘]= {‘reply_count‘:temp,‘content‘:obj.content,
                      ‘user__name‘:obj.user.username,
                      ‘create_date‘:obj.create_date.strftime(‘%Y-%m-%d %H:%M:%S‘)}
        ret[‘status‘] = 1
    except Exception,e:
        ret[‘message‘] = e.message
        
    
    return HttpResponse(json.dumps(ret))
    

 

前端:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel=‘stylesheet‘ href=‘/static/css/common.css‘>
	<style>
		.hide {
			display:None;
		}
	
	</style>
</head>
<body>

	<div class=‘pg-header‘>
		<div class=‘head-content‘>
			<a href="/" class="digg-logo"></a>
			<div class=‘header-menu‘>
				<a href=‘/index‘ class=‘tb active‘>全部</a>
				<a href=‘/index‘ class=‘tb‘>1024区</a>
				<a href=‘/index‘ class=‘tb‘>老男孩</a>
				<a href=‘/index‘ class=‘tb‘>IT民工</a>
			</div>
			
		</div>
		<div class=‘header-search‘></div>

	</div>
	<div class=‘pg-body‘>
	{% for item in data %}
	<br>
		<div class=‘part1‘>
			<a href=‘{{item.url}}‘>{{item.title}}</a>
		</div>
		<div class=‘part2‘>
			{{item.summary}}
		</div>
		<div class=‘part3‘>
			<a href=‘‘ onclick=‘Favor(this,{{item.id}})‘>点赞{{item.favor_count}}</a>
			<a href=‘‘ class=‘reply‘ onclick=‘Reply(this,{{item.id}})‘>评论{{item.reply_count}}</a>
			<span>{{item.create_date|date:‘Y-m-d H:i:s‘}}</span>
		</div>
		<!-- 下面自定义一个属性has-input用于JAVA里的判断是否有穿入框了 -->
		<div  has-input=0 class=‘part4 hide‘>
		<!--这底下两个CSS用于下面Java的处理 -->
			<div class=‘replys‘></div>
			<div class=‘input‘>
				<lable>请输入内容:</lable>
				<textarea></textarea>
				<!-- 这里添加item.id,是提交的时候要关联到这个新闻,不能放到其他的新闻里去
				 这里的this,一样通过此标签的上一个标签,就是提交的内容 -->
				<input type=‘button‘ value=‘提交‘ onclick=‘Submit(this,{{item.id}})‘>
			</div>
		</div>
		
	{% endfor %}
	</div>
	
	
	<!-- 遮罩层开始 -->
	<div id=‘shade‘ class=‘shade hide‘></div>
	<!-- 遮罩层结束 -->
	<!-- 加载层开始 -->
	<div id=‘loading‘ class=‘loading hide‘></div>
	<!-- 加载层结束 -->
	
	<div class=‘pg-buttom‘></div>

	<script src=‘/static/jquery/jquery-1.12.4.js‘></script>
	<script type=‘text/javascript‘>
	//jquery还是有错误,无法正常使用20170517
		function Favor(doc,id){
			$.ajax({
				//注意Ajax里不能用冒号,要用逗号
				url:‘/addfavor/‘,
				data:{id:id},
				type:‘POST‘,
				sussess:function(arg){
					var obj = jQuery.parseJSON(arg);
					//console.log(obj);
					if(obj.status==1){
						var temp = ‘赞‘ + obj.data;
						$(doc).text(temp);
					}else{
						//出错的时候未能正常显示出来
						alert(obj.message)	
					}
					}
			})
		}
		/*
		这里测试始终不成功,不能看到Lable里值,不能去掉CSS
		function Reply(content,id){
			//console.log($(‘#content‘).attr(‘has-input‘));
			//$(‘#rid‘).removeClass(‘part4‘);
			//toggleClass反复的加减CSS
			//$(‘#content‘).toggleClass(‘hide‘);
			var html = $(‘#id1‘).parent().next().first()
			console.log(html)
			//removeClass(‘hide‘);	
		}  */
		
		/* 这是第6课的内容
		function Reply(doc,id){
			$.ajax(){
				url:‘/getreply/‘,
				type:‘POST‘,
				data:{nid,id},
				sussess:function(callback){
					//callback是后台返回的数据
					console.log(callback;)
					var obj = jQuery.parseJSON(callback);
					$.each(obj,function(k,v){
						//当前标签和父亲标签的下一个标签的第一个标签
						//$(doc).parent().next().first().text(‘0000‘)
			            var temp = ‘<p>‘ + v.fields.content + ‘</p>‘;
			         	 //这里找到.reply的CSS,先清除当前的内容,不然会出现重复
			            $(doc).parent().next().find(‘.replys‘).empty();  
			          	//这里找到.reply的CSS,再将返回的数据插进去
						$(doc).parent().next().find(‘.replys‘).append(temp);
			            });
			            //这里点击时会去掉当前的hide的CSS
			            $(doc).parent().next().toggleClass(‘hide‘);
					
					
				}	
			}
			//console.log($(‘#content‘).attr(‘has-input‘));
			//$(‘#rid‘).removeClass(‘part4‘);
			//toggleClass反复的加减CSS
			//$(‘#content‘).toggleClass(‘hide‘);
			var html = $(‘#id1‘).parent().next().first()
			console.log(html)
			//removeClass(‘hide‘);	
		}
		*/
		
		//这是第7课的内容
		function Reply(doc,id){
			$.ajax(){
				url:‘/getreply/‘,
				type:‘POST‘,
				data:{nid:id},
				sussess:function(callback){
					//callback是后台返回的数据
					console.log(callback;)
					var obj = jQuery.parseJSON(callback);
					//放在这里,不会每次都清空掉,这样可以显示所有记录
					$(doc).parent().next().find(‘.replys‘).empty();  
					$.each(obj,function(k,v){
						//当前标签和父亲标签的下一个标签的第一个标签
						//$(doc).parent().next().first().text(‘0000‘)
			            temp = ‘<p>‘ + v.username + ‘:‘ + v.content + ‘---‘ + v.create_date + ‘</p>‘;
			            
			         	 //这里找到.reply的CSS,先清除当前的内容,不然会出现重复,这样只会显示最新的内容,正常要放到循环外面
			            //$(doc).parent().next().find(‘.replys‘).empty();  
			          	//这里找到.reply的CSS,再将返回的数据插进去
						$(doc).parent().next().find(‘.replys‘).append(temp);
			            });
			            //这里点击时会去掉当前的hide的CSS
			            $(doc).parent().next().toggleClass(‘hide‘);	
				}	
			}
		}

		function Submit(doc,id){
			//上一个标签
			var value = $(doc).prev().val();
			//提交后清除输入框
			$(doc).prev().val(‘‘);
			$(‘#shade,loading‘).removeClass(‘hide‘);
			$.ajax(){
				url:‘/submitreply/‘,
				type:‘POST‘,
				data:{nid:id,data:value},
				sussess:function(callback){
					//callback是后台返回的数据
					console.log(callback;)
					var callback = jQuery.parseJSON(callback);
					if (callback.status==1){
						//把数据Append到回复列表中
						temp = ‘<p>‘ + callback.data.username + ‘:‘ + callback.data.content + ‘---‘ + callback.data.create_date + ‘</p>‘;
						$(doc).parent().prev().append(temp)
						
						//底下两行代码可以让评论数实时的更新,添加一条时自动计数
						//先提交到后台,正常保存后自动加1,同时将新的内容和数值提交到前台
						count = ‘评论‘ + callback.data.reply_count
						$(doc).parent().parent().prev().find(‘.reply‘).text(count)
					}else{
						alert(‘失败‘)}
					}
					$(‘#shade,loading‘).addClass(‘hide‘);
				}
			}
	</script>
</body>
</html>

  
































































































































































































































以上是关于Python学习day14 BBS功能和聊天室的主要内容,如果未能解决你的问题,请参考以下文章

python2.0_day21_web聊天室一

python学习 day14 进程和线程

DAY87-BBS项目 数据库设计与简单登陆验证码

python基础day14 装饰器详情

Python之路,day22-BBS基础

python学习-day14