python自动化开发-[第二十二天]-bbs多级评论、点赞、上传文件

今日概要:

  1、related_name和related_query_name的区别

  2、through_fields的用途

  3、django的事务提交

  4、点赞的动画效果

  5、多级评论的原理

  6、上传文件

  7、request.post用法

  8、如果保留原来的页面

一、related_name和related_query_name的区别

  related_name,用于定义反向关联时候,使用的字段名称

  related_query_name 用于反向查询related_query_name + _set进行查询

  例子:  

class A:
	title = models.CharField()
obj = models.A.objects.get(id=1)
obj.b_set.all()
obj.xxxxxx_set.all() # related_query_name='xxxxxx'
obj.uuuu.all()       # related_name='uuuu'

obj.x
obj.u

class B:
	xx ..xx
	fk1 = models.ForignKey(related_name='x')
	fk2 = models.ManyToMany(related_name='u')

models.B.objects.filter(fk__title='xx')

二、through_fields的用途

  through_fields = (在关系表中与当前表建立FK关系的字段名称,在关系表中与目标表建立的FK关系字段名称)

  例子:

likes = models.ManyToManyField(to='UserInfo',through="Like",through_fields=('new','user')) #当前表是new表

 

三、django的事务提交

  保持两条sql的同时正确才进行插入动作

	from django.db import transaction
	with transaction.atomic():
          models.Like.objects.create(nnew_id=new_id,uuser_id=uid)
          models.News.objects.filter(id=new_id).update(like_count=F('like_count') + 1)
        response.code = 999

    返回值封装:

class BaseResponse(object):
	def __init__(self):
		self.status = False
		self.data = None
		self.msg = None

	def get_dict(self):
		return self.__dict__


class LikeResponse(BaseResponse):
	def __init__(self):
		self.code = 0
		super(LikeResponse,self).__init__()


json.dumps(对象.__dict__)
json.dumps(对象.get_dict())

四、点赞的动画效果

  *在ajax中操作回调函数中的 $(this)已经不是原来的$(this) 

  解决方法:通过一个变量来传递

  应用内容:css中的position:fixed,absolute,relative setInterval:定时器

js代码:  

$(function () {
    bindLikeEvent();
});

function bindLikeEvent() {
    $('.new-like').click(function () {
        // 获取当前新闻ID
        var newId = $(this).attr('new-id');
        var $this = $(this);
        $.ajax({
            url: '/do_like.html',
            type: "POST",
            data: {'newId': newId},
            dataType: 'JSON',
            success:function (arg) {
                if(arg.status){
                    var origin = $this.text();
                    var count = parseInt(origin);
                    if(arg.code == 666){
                        $this.text(count - 1 );
                        showLikeCount($this,'-1');

                    }else if(arg.code == 999){
                        $this.text(count + 1 );
                        showLikeCount($this,'+1');

                    }
                }else{
                    alert(arg.msg);
                }
            }

        })
    })
}


function showLikeCount($this,text) {
   var fontSize = 5;
   var top = 0;
   var right = 0;
   var opacity = 1;
   var tag = document.createElement('span');
   tag.innerText = text;
   tag.style.position = "absolute";
   tag.style.fontSize = fontSize + "px";
   tag.style.top = top + "px";
   tag.style.right = right + "px";
   tag.opacity = opacity;

   $this.after(tag);

   var obj = setInterval(function () {
       fontSize += 5 ;
       top -= 5;
       right -= 5 ;
       opacity -= 0.1 ;
       tag.style.fontSize = fontSize + "px";
       tag.style.top = top + "px";
       tag.style.right = right + "px";
       tag.style.opacity = opacity;
       if (opacity <= 0 ){
           clearInterval(obj);
           tag.remove()
       }
   },100)


}
</script>

 五、多级评论的原理

  知识点:字典和列表,通过引用赋值,一个修改全部都改变

      递归

  

#!/usr/bin/python
# -*- coding:utf-8 -*-


def build_comment_data(li):
    dic = {}   #定义一个空字典dic
    for item in li:
        item['children'] = []  #列表字典中新增一个key叫children,value为空
        dic[item['id']] = item   #给空字典dic赋值 key是列表中字典中的id,value是列表字典

    result = []  #定义一个空列表,存最后的结果

    for item in li:   #item是li列表中的每一行字典
        pid = item['parent_id']   #pid是取每一行字典中parent_id的值
        if pid:   #如果每一行字典中parent_id有值
            dic[pid]['children'].append(item) #则找到字典中pid的那一行,把item加到children里
        else:
            result.append(item)   #否则把parent_id没有值的加到result列表中
    # for i in result:
    #     print(i)
    return result


def build_comment_tree(com_list1):
    tpl = """
        <div class="item>
            <div class="title">{0}:{1}</div>
            <div class="body>{2}</div>
        </div>
    """
    #这里的{0}{1}{2}都是占位符

    html=""
    # print(com_list1)
    # for i in com_list1:
    #     print(i)
    for item in com_list1:
        if not item['children']:  #如果字典中没有children
            html += tpl.format(item['user'],item['content'],"") #format给占位符传值,第三个值为空
        else:
            html += tpl.format(item['user'], item['content'], build_comment_tree(item['children']))
            #如果有子children则把build_comment_tree函数自己再执行一遍,把孩子传进去(孩子也是一个完整的字典)
    return html


def comment_list():
    li = [
        {'id': 1, 'user': '银秋良', 'content': '灌我鸟事', 'parent_id': None},
        {'id': 2, 'user': '银秋良', 'content': '管我鸟事', 'parent_id': None},
        {'id': 3, 'user': '型谱', 'content': '你个文盲', 'parent_id': 1},
        {'id': 4, 'user': '详解', 'content': '好羡慕你们这些没脸的人呀', 'parent_id': 2},
        {'id': 5, 'user': '银秋良', 'content': '你是流氓', 'parent_id': 3},
        {'id': 6, 'user': '银秋良', 'content': '你冷库无情', 'parent_id': 5},
        {'id': 7, 'user': '银秋良', 'content': '你才冷酷无情', 'parent_id': 4},
        {'id': 8, 'user': '银秋良', 'content': '你无理取闹', 'parent_id': 4},
    ]
    com_list = build_comment_data(li)

    html = build_comment_tree(com_list)
    print(html)

if __name__ == '__main__':
    comment_list()

   知识回顾:  

l = [1,2,4,5,6] #迭代器
for i in l:   #迭代器对象
    # 迭代器出现报错 l.__iter__() next()取到空的情况,迭代器对象不会

for j in l:
    print(i)

    引用类型应用:

li = [
    {'user':'xxx','pwd':'xxx','id':1,"children":[],'parent_id':None},
    {'user':'xxx','pwd':'xxx','id':2,"children":[],'parent_id':None},
    {'user':'xxx','pwd':'xxx','id':3,"children":[],'parent_id':1},
    {'user':'xxx','pwd':'xxx','id':4,"children":[],'parent_id':2},
    {'user':'xxx','pwd':'xxx','id':5,"children":[],'parent_id':1},
    {'user':'xxx','pwd':'xxx','id':6,"children":[],'parent_id':3},
]
#结果:
# result = [
#     {'user':'xxx','pwd':'xxx','id':1,"children":[{'user':'xxx','pwd':'xxx','id':3,"children":[ {'user':'xxx','pwd':'xxx','id':6,"children":[],'parent_id':3},],'parent_id':1},{'user':'xxx','pwd':'xxx','id':5,"children":[],'parent_id':1},],'parent_id':None},
#     {'user':'xxx','pwd':'xxx','id':2,"children":[{'user':'xxx','pwd':'xxx','id':4,"children":[],'parent_id':2},],'parent_id':None},
# ]

dict = {}
for i in li:
    dict[i['id']] = i

a = []
for k,v in dict.items():
    if v['parent_id']:
        dict[v['parent_id']]["children"].append(v)
    else:
        a.append(v)

print(a)

   javascript实现多级评论:

  

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide {
            display: none;
        }
        .body{
            margin-left: 30px;
        }

    </style>
</head>
<body>
    <h1>多级评论</h1>
    <a id="a1" href="#" onclick="myClick()">点我</a>
{#    {{ comment_list | safe }}#}

    <script src="/static/jquery-3.2.1.js"></script>
    <script>

            function my_iter(arg) {
                 var h = "";
                    $.each(arg,function (k,v) {
                        if (v['children']){
                            h += '<div class="item"><div class="title">' + v['user'] + ':' + v['content'] + '</div> <div class="body">' + my_iter(v['children']) + '</div></div>'
                        }else{
                            h += '<div class="item"><div class="title">' + v['user'] + ':' + v['content'] + '</div><div class="body"></div></div>'
                        }
                    });
                return h
        }


        $(function () {
            $('body').on('click',".title",function () {
                if ($(this).next().hasClass('hide')){
                    $(this).next().removeClass('hide')
                }else{
                    $(this).next().addClass('hide')
                }
            })
        });
        function myClick() {
            $.ajax({
                url:'/comment',
                type:"POST",
                data:"1",
                dataType:"JSON",
                success:function (arg) {
                       console.log(my_iter(arg));
                    $('#a1').after(my_iter(arg))
                }
            })
        }
        
    </script>
</body>
</html>

六、上传文件  

  - 基于FormData
  - 缺点,兼容性不好
  - 优点,Ajax直接发送

  - 伪Ajax,兼容性更好
  - iframe,天生局部刷新
  - form,天生整个页面刷新

七、request.post用法

- 如何通过python代码发送post数据?
	URL: http://127.0.0.1:8003/asset.html
	
	
	客户端:
		import requests
		# response = requests.get('http://127.0.0.1:8003/asset.html')
		# print(response.text)
		data_dict = {
			'k1':'v1',
			'k2':'v2'
		}
		# content-type: application/x-www-form-urlencoded
		# response = requests.post('http://127.0.0.1:8003/asset.html',data=data_dict)
		# print(response.text)

		# content-type: appcation/json
		response = requests.post('http://127.0.0.1:8003/asset.html',json=data_dict)
		print(response.text)
		
	服务端Django:
		from django.views.decorators.csrf import csrf_exempt,csrf_protect

		@csrf_exempt
		def asset(request):
			if request.method == "GET":
				return HttpResponse('收到:GET')
			else:
				print(request.POST)
				print(request.body)
				return HttpResponse('收到:POST')

 八、如果保留原来的页面 

request.GET
from django.http.request import QueryDict
要点:
	POST,不要写action

 

例子:  

def host_list(request):
    print(request.GET,type(request.GET))
    # request.GET._mutable = True

    obj = QueryDict(mutable=True)
    obj['_zhaofengfeng'] = request.GET.urlencode() # page=10&id=1
    url_param = obj.urlencode()

    hosts = ['c1.com','c2.com','c3.com']
    return render(request,'host_list.html',{'hosts':hosts,'url_param':url_param})

def add_host(request):
    if request.method == "GET":
        return render(request,'add.html')
    else:
        url_params = request.GET.get('_zhaofengfeng')
        host = request.POST.get('hostname')
        url ="/host_list.html?"+url_params
        return redirect(url)
posted @ 2017-10-14 09:01  dragonliu  阅读(382)  评论(0编辑  收藏  举报