zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    C++ Builder XE2随意学习 (12) > DevExpress Dock拖动框架实现
    C++ Builder XE2随意学习 (14) > 窗口透明处理
    C++ Builder XE2随意学习(9) > 安装实录
    C++ Builder XE2随意学习 (13) > Gdiplus
    C++ Builder XE2随意学习 (10) > AlphaControls控件使用初探
    ASP.NET 4.0 视频教程
    C++ Builder XE2随意学习 (11) > DevExpress Ribbon界面效果
    C++ Builder XE2随意学习 (7) > RAD Studio XE2 – Setting it up for a Mac
    C++ Builder XE2随意学习(8) > 快速入门教程
    jQuery实现倒计时效果
  • 原文地址:https://www.cnblogs.com/liujiliang/p/7665662.html
Copyright © 2011-2022 走看看