• Python学习笔记第二十五周(Django补充)


      1、render_to_reponse()

        不同于render,render_to_response()不用包含request,直接写template中文件

      2、locals()

        如果views文件中的函数里变量过多的话,可以在render或render_to_response()里面直接增加render(request,'index.html',locals())这样在前端界面渲染的时候可以直接写变量名

        locals()的缺点是不想传递过去的变量也传递过去了

      3、JS中的方法:

        a: hover(f1,f2)

          例子:

          $(".outer").hover(f1,f2) 其中f1表示鼠标进入时操作,f2表示鼠标退出时操作

          hover比mouseover()和mouseout()的优点在于hover一个方法可以表示两个动作

          $(".outer").hover(function(){

            clearInterval(time);

            },function(){

            time=setInterval(move,1500)#每一点五秒执行setInterval动作

             })

        b:关于轮播图乱序问题解决:

        $('.num .li').eq(i).stop().fadeIn(1000).siblings().stop().fadeOut(1000);#加入stop表示先将播放全部停止然后在做fadeIn和fadeOut操作

       4、template中,如果要简单标注索引可以使用

        {{  forloop.counter}}  从1开始

        {{ forloop.counter0}} 从0开始

        {{forloop.revcounter}} 从最大开始

        {{ forloop.revcounter0}}从最大开始到0结束

                模板语言中,引用base模板中内容,使用{{ block.super }}

      5、ORM操作

      增加:

        #create方式一:Author.objects.create(name="Alvin")   

        #create方式二:Author.objects.create(**{"name":"Alvin"})  推荐使用

        如果有外键:

          一对多:

          <1>models.Book.objects.create(title="python",price=2,publish_id=2)  #其中publish为外键关联,默认使用id,所以publish_id自动生成

          <2>models.Book.objects.create(title="python",price=2,publish=obj)#publish绑定的是一对多里面一的那个对象,也就是publish对应的   推荐

                                          #obj代表一个object对象

                      

          多对多:

          1、自动创建

            add()   remove()

          -----------正向绑定

           book=models.Book.objects.filter(id=2)[0]

          authors=models.Author.objects.filter(id__gt=2)    

          book.author.add(*authors)

          ------------反向绑定

          authors=models.Author.objects.filter(id=2)[0]

          books=models.Book.objects.filter(id__gt=2)     

          author.book_set.add(*books)                  #book_set组合在一起组成一个QuerySet ,这个是django自带的功能

        #save方式一:author=Author(name="alvin")

                author.save()

        #save方式二:authorAuthor()

              author.name="alvin"

              author.save()

        2、手动创建

           class BOOKAuthor(models.Model):

            author=models.ForeignKey('Author')

            book=models.ForeignKey('Book')

            class Meta: 

              unique_together=['author','book']  #联合唯一

        自己写第三张表

        ManytoMany 通过两个ForeignKey完成

        OnetoOne     通过一个ForeignKey,uiqueTrue来完成

        

      删除:

        models.Book.objects.filter(id=1).delete()

      改:

        第一种:author=Author.objects.get(id-5)

            authort.name='tenglan'

            author.save()

        第二种:Publisher.objects.filter(id=5).update(name='Ameriacan publshler‘)#不能用get(id=2)来查找锁定

      查询API:

        filter(**kwargs):   它包含了所有刷选条件匹配的对象

        all():          查询所有结果

        get(**kwargs):            返回与所筛选条件匹配对象,返回结果有且只有一个,如果一个都没匹配到会报错

        ---------------------------------

        下面方法都是对查询结果再进行处理,日不objects.filter().values()

        vaules(*filed)       返回一个valuequeryset-一个特殊的queryset,运行后得到的并不是一系列model实例对象,而是一个可迭代的字典序列

        exclude(**kwargs)    包含了与所给刷选条件不匹配的对象

        order_by(*filed)     对查询结果排序,如果按照从大到小排序,可以使用order_by("-id") 这种方式来进行

        reverse()      对结果反向排序

        distinct()         从返回结果中剔除重复记录

        values_list(*filed)   它与values()非常类似,返回的是一个元组序列,values返回的是字典序列

         count()          返回数据库中匹配查询QuerySet的对象数量

           first()          返回第一条记录

        last()                      返回最后一条记录

         exists()      如果queryset包含数据,返回True,否则返回Flase

      

        惰性机制:

        所谓惰性机制,Pbulisher.objects.all()或者.filter()等都只是返回一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行。

        QuerySet特点:

        1、可迭代

        2、可切片

        #objs=models.Book.objects.all()#(obj1,obj2,obj3,.)

        #QuerySet 可迭代

        for obj in objs:每一个obj就是一个行对象

          print("obj:",obj)

        #QuerySet 可切片

        #print(objs[1])

        #print(objs[1:4])

        #print(objs[::-1])

    注意,这里因为update返回的是一个整形,所以没法用query属性,对于每次创建一个对象,想显示对应的row sql,需要在settings加上日志记录部分:

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    
    LOGGING
    View Code

        下划线使用:

        一、单表查询

        models.Book.objects.filter(id__gt=2)

        models.Book.objects.filter(id__lt=2)

        models.Book.objects.filter(id__in=[1,3,4,7]) 包含,用__in

        models.Book.objects.filter(title__contian="P") #contain表示包含,icontain表示不区分大小写

        models.Book.objects.filter(title__startwith="P")

        models.Book.objects.filter(title__endwith="P")  

        二、关联表查询

        models.Publish.objects.filter(book__title="pytohn",book_id=5).values("name").distinct()  #多个条件

        models.Book.objects.filter(id__gt=2,id__lt=5)       

        models.Book.objects.filter(publish__name="清华出版社").values("title")

        models.Book.objects.filter(title="python").values(“publisher__name”)

         三、聚合和分组查询

        aggregate(*args,**kwargs):

        通过QuerySet进行计算,返回一个聚合值的字典,aggregate()中每一个参数都指定一个包含在字典中的返回值,即在查询集上生成聚合

        

    from django.db.models import Avg,Min,Sum,Max
    
    从整个查询集生成统计值。比如,你想要计算所有在售书的平均价钱。Django的查询语法提供了一种方式描述所有
    图书的集合。
    
    >>> Book.objects.all().aggregate(Avg('price'))
    {'price__avg': 34.35}
    
    aggregate()子句的参数描述了我们想要计算的聚合值,在这个例子中,是Book模型中price字段的平均值
    
    aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的
    标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定
    一个名称,可以向聚合子句提供它:
    >>> Book.objects.aggregate(average_price=Avg('price'))
    {'average_price': 34.35}
    
    
    如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
    >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
    {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
    View Code

        

        annotate(*args,**kwargs):

           可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。

               查询alex出的书总价格 :

          Book.objects.filter(author__name="alex").values('title')

          Book.objects.filter(author__name="alex").aggregate(Sum('price'))

        查询各个作者出的书的总价格,这里就涉及到分组了,分组条件是author__name

          Book.objects.values("author__name").annotate(Sum('price'))

        查询各个出版社最便宜的书价是多少

          Book.objects.values('publisher__name').annotate(MIn('price'))

        F查询和Q查询

        仅仅靠单一的关键字参数查询已经很难满足查询要求。此时Django为我们提供了F和Q查询:

          

    # F 使用查询条件的值,专门取对象中某列值的操作
    
        # from django.db.models import F
        # models.Tb1.objects.update(num=F('num')+1)
    
    
    # Q 构建搜索条件
        from django.db.models import Q
    
        #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
        q1=models.Book.objects.filter(Q(title__startswith='P')).all()
        print(q1)#[<Book: Python>, <Book: Perl>]
    
        # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
        Q(title__startswith='P') | Q(title__startswith='J')
    
        # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
        Q(title__startswith='P') | ~Q(pub_date__year=2005)
    
        # 4、应用范围:
    
        # Each lookup function that takes keyword-arguments (e.g. filter(),
        #  exclude(), get()) can also be passed one or more Q objects as
        # positional (not-named) arguments. If you provide multiple Q object
        # arguments to a lookup function, the arguments will be “AND”ed
        # together. For example:
    
        Book.objects.get(
            Q(title__startswith='P'),
            Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
        )
    
        #sql:
        # SELECT * from polls WHERE question LIKE 'P%'
        #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
    
        # import datetime
        # e=datetime.date(2005,5,6)  #2005-05-06
    
        # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
        # 正确:
        Book.objects.get(
            Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
            title__startswith='P')
        # 错误:
        Book.objects.get(
            question__startswith='P',
            Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
    View Code

        

      6、Ajax  

      AJAXAsynchronous Javascript And XML)翻译成中文就是异步JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

      AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

      

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
    <script type="text/javascript">
    window.onload = function() {//当文档加载完毕时执行本函数
        var form = document.getElementById("form1");//获取表单元素对象
        form.onsubmit = function() {//给表单元素添加一个监听,监听表单被提交事件
            var usernameValue = form.username.value;//获取表单中名为username的表单元素值
            if(!usernameValue) {//判断该值是否为空
                var usernameSpan = document.getElementById("usernameSpan");//得到usernmae元素后的<span>元素
                usernameSpan.innerText = "用户名不能为空!";//设置span元素内容!
                return false;//返回false,表示拦截了表单提交动作
            }
            return true;//不拦截表单提交动作
        };
    };
    </script>
    </head>
     <body>
    <h1>注册页面</h1>
    <form action="" method="post" id="form1">
    用户名:<input type="text" name="username"/>
    <span id="usernameSpan"></span>
    <br/>
    密 码:<input type="password" name="password"/>
    <span id="passwordSpan"></span>
    <br/>
    <input type="submit" value="注册"/>
    
    </form>
      </body>
    </html>
    
    js实现的局部刷新
    View Code

      Ajax常见应用场景

      

    当我们在百度中输入一个“老字后,会马上出现一个下拉列表!列表中显示的是包含字的4个关键字。

    其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这4个关键字显示在下拉列表中。

    • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
    • 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

      当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示用户名已被注册!

    • 整个过程中页面没有刷新,只是局部刷新了;
    • 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;

        

      Ajax优缺点

      

    优点:

    • AJAX使用Javascript技术向服务器发送异步请求;
    • AJAX无须刷新整个页面;
    • 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;

    缺点:

    • AJAX并不适合所有场景,很多时候还是要使用同步交互;
    • AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数增多了,导致服务器压力增大;
    • 因为AJAX是在浏览器中使用Javascript技术完成的,所以还需要处理浏览器兼容性问题;

     

       Ajax技术:

    四步操作:

    • 创建核心对象;
    • 使用核心对象打开与服务器的连接;
    • 发送请求
    • 注册监听,监听服务器响应。

    XMLHTTPRequest

    • open(请求方式, URL, 是否异步)
    • send(请求体)
    • onreadystatechange,指定监听函数,它会在xmlHttp对象的状态发生变化时被调用
    • readyState,当前xmlHttp对象的状态,其中4状态表示服务器响应结束
    • status:服务器响应的状态码,只有服务器响应结束时才有这个东东,200表示响应成功;
    • responseText:获取服务器的响应体

     

      Ajax实现

       准备工作(后台设定):

    def login(request):
        print('hello ajax')
        return render(request,'index.html')
     
    def ajax_get(request):
        return HttpResponse('helloyuanhao')
    View Code

      

    AJAX核心(XMLHttpRequest

      其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象。所有的异步交互都是使用XMLHttpServlet对象完成的。也就是说,我们只需要学习一个Javascript的新对象即可。

    var xmlHttp = new XMLHttpRequest();(大多数浏览器都支持DOM2规范)

    注意,各个浏览器对XMLHttpRequest的支持也是不同的!为了处理浏览器兼容问题,给出下面方法来创建XMLHttpRequest对象:

    function createXMLHttpRequest() {
            var xmlHttp;
            // 适用于大多数浏览器,以及IE7和IE更高版本
            try{
                xmlHttp = new XMLHttpRequest();
            } catch (e) {
                // 适用于IE6
                try {
                    xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                } catch (e) {
                    // 适用于IE5.5,以及IE更早版本
                    try{
                        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                    } catch (e){}
                }
            }            
            return xmlHttp;
        }
    View Code

    打开与服务器的连接(open方法)

    当得到XMLHttpRequest对象后,就可以调用该对象的open()方法打开与服务器的连接了。open()方法的参数如下:

    open(method, url, async)

    • method:请求方式,通常为GETPOST
    • url:请求的服务器地址,例如:/ajaxdemo1/AServlet,若为GET请求,还可以在URL后追加参数;
    • async:这个参数可以不给,默认值为true,表示异步请求;
    var xmlHttp = createXMLHttpRequest();
    xmlHttp.open("GET", "/ajax_get/", true); 
    View Code

      

      发送请求

      

    当使用open打开连接后,就可以调用XMLHttpRequest对象的send()方法发送请求了。send()方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。

    注意:若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!

    xmlHttp.send(null);

      

      接收服务器响应

      

    当请求发送出去后,服务器端Servlet就开始执行了,但服务器端的响应还没有接收到。接下来我们来接收服务器的响应。

    XMLHttpRequest对象有一个onreadystatechange事件,它会在XMLHttpRequest对象的状态发生变化时被调用。下面介绍一下XMLHttpRequest对象的5种状态:

    • 0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
    • 1:请求已开始,open()方法已调用,但还没调用send()方法;
    • 2:请求发送完成状态,send()方法已调用;
    • 3:开始读取服务器响应;
    • 4:读取服务器响应结束。 

    onreadystatechange事件会在状态为1234时引发。

      下面代码会被执行四次!对应XMLHttpRequest的四种状态!

    xmlHttp.onreadystatechange = function() {
                alert('hello');
            };

      但通常我们只关心最后一种状态,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XMLHttpRequest对象的readyState属性来得到XMLHttpRequest对象的状态。

      

    xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4) {
                    alert('hello');    
                }
            };

      

      其实我们还要关心服务器响应的状态码是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XMLHttpRequest对象的status属性得到服务器的状态码。

      最后,我们还需要获取到服务器响应的内容,可以通过XMLHttpRequest对象的responseText得到服务器响应内容。

    xmlHttp.onreadystatechange = function() {
                if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
                    alert(xmlHttp.responseText);    
                }
            };
    View Code
  • 相关阅读:
    (5)基于协同过滤推荐算法的图书推荐研究
    (4)推荐系统评测方法和指标分析
    (3)浅析机器学习在推荐系统中的应用
    (2)协同过滤推荐算法概述 摘要
    (1)推荐系统概述 -- 摘要
    30+简约时尚的Macbook贴花
    20+非常棒的Photoshop卡通设计教程
    20+WordPress手机主题和插件【好收藏推荐】
    30+WordPress古典风格的主题-古典却不失时尚
    配置FCKeditor_2.6.3+fckeditor-java-2.4
  • 原文地址:https://www.cnblogs.com/xiaopi-python/p/7460644.html
Copyright © 2020-2023  润新知