• 02-django查询


     
    目录
    (一)查询
    1 、基本查询(等于、大于、包含字符、日期、字段比较、逻辑)
    2 、关联查询(即为join查询)(一对多、多对多、一对一)
    3 、聚合查询(统计查询)
    (二)关联对象(已知A表的一条记录,查B表的一条或多条记录)
    1 、已知一本图书,查询书中所有的英雄
    2 、已知一个英雄,查询图书
    3 、自关联
     

     
    (一)查询
    实现sql中where的功能,调用过滤器filter()、exclude()、get(),下面以filter()为例
    属性名称和比较运算符间使用两个下划线(双下划线),所以属性名不能包括多个下划线
    属性名称__比较运算符=值
    注意:没有“__运算符”部分,表示等于。
     
    1 、基本查询(等于、大于、包含字符、日期、字段比较、逻辑)
     
        list=BookInfo.books.filter(id__exact=3)
        list=BookInfo.books.filter(id=3)
        list=BookInfo.books.filter(id__lte=3)
        list=BookInfo.books.filter(id__in=[1,3,5])  # 查询编号为1或3或5的图书
     
        list=BookInfo.books.filter(btitle__contains="传")  # 查询书名包含‘传’的图书
        list=BookInfo.books.filter(btitle__endswith="部")  # 查询书名以‘部’结尾的图书
        list=BookInfo.books.filter(btitle__isnull=False)  # 查询书名不为空的图书
     
        list=BookInfo.books.filter(bpub_date__year=1980)  # 查询1980年发表的图书
        list=BookInfo.books.filter(bpub_date__gt=date(1990,1,1))
     
        list=BookInfo.books.filter(bread__gte=F("bcommet"))  #  两个字段比较
     
        list=BookInfo.books.filter(Q(bread__gt=20) & Q(id__gte=3))  # 逻辑与
        list=BookInfo.books.filter(bread__gt=20,id__gte=3)
        list=BookInfo.books.filter(bread__gt=20).filter(id__gte=3)
     
        list=BookInfo.books.filter(Q(bread__gt=20) | Q(id__gte=3))  # 逻辑或
        list=BookInfo.books.filter(~Q(id__gte=3))  # 逻辑非
     
    2 、关联查询(即为join查询)(一对多、多对多、一对一)
    (1)理解
    关联查询:就是join查询
    类似sql中的inner join。
    如果不加__gte、__contains等运算,就是等于运算,此时就完全和inner join效果相同。
    如果有__gte、__contains等运算,就属于inner join的子集。
    前提是建立外键,使表相互关联。
     
    (2)关联的变化
    以1:N的关系举例:
    如,在N端建立外键属性hbook
    # 英雄模型类
    class HeroInfo(models.Model):
        hbook=models.ForeignKey('BookInfo')
    此时,会有以下变化:
     
    1)类层面:
    在1端,类层面会生成N端的对象heroinfo:
    # 查询图书,要求图书中英雄的描述包含‘八’
    list=BookInfo.books.filter(heroinfo__hcontent__contains='八')
     
    在N端,类层面已定义1端的对象hbook(就是N端的外键属性hbook)。同时N端的mysql表中生成hbook_id字段。
    # 查询书名为“天龙八部”的所有英雄
    list=HeroInfo.objects.filter(hbook__btitle='天龙八部')
     
     
    2)对象层面:
    在1端,对象层面会生成heroinfo_set属性,表示某一本书中的所有英雄。
    如:查找某本书中的所有英雄。
    book.heroinfo_set.all()
     
     
    在N端,对象层面hbook属性(就是N端的外键属性hbook),表示某个英雄对应的图书对象。
    如:已知某个英雄对象,找到对应书的书名:
    hero.hbook.htitle
     
    小结:外键引发了4件事
    外键所在N端:
    对其本身而言,hbook表示1端的一个图书对象book
    对N端而言,mysql表中产生了hbook_id字段
     
    在1端:
    多了heroinfo属性,用于类。
    多了heroinfo_set属性,用于对象。
     
     
    拓展:关系型数据库的关系包括三种类型:
    ForeignKey:一对多,将字段定义在多的一端中。
    ManyToManyField:多对多,将字段定义在两端中。
    OneToOneField:一对一,将字段定义在任意一端中。
     
    3 、聚合查询(统计查询)
    使用aggregate()过滤器调用聚合函数
    聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中
     
        # 查询图书的总阅读量
        list_sum=BookInfo.books.aggregate(Sum('bread'))
     
        # 查询图书总数   使用count时一般不使用aggregate()过滤器
        # list_count=BookInfo.books.aggregate(Count('id'))
        list_count=BookInfo.books.count()
     
    使用大写的聚合函数查询,得到的结果是一个字段,如{'bread__sum':12}。
    字典的键名为:被查字段名+双下划线+小写聚合函数名。如下图:
    (二)关联对象(已知A表的一条记录,查B表的一条或多条记录)
    关联对象的查询前提是,必须用外键建立关系如1:N、N:N、1:1
     1、已知一本图书,查询书中所有的英雄
        # 图书和英雄为1:N的关系,关系字段定义在了英雄类中
        # django会为图书类生成一个属性heroinfo_set
        # 查询编号为1的图书
        book=BookInfo.books.get(pk=1)
        # 获得book图书的所有英雄
        bookhero=book.heroinfo_set.all()
     
    在模板中,不能使用方法,则不要all后面的括号即可

    {% for hero in b.heroinfo_set.all %}
      <li>{{ hero.hname }}</li>
    {% endfor %}

     
    2 、已知一个英雄,查询图书
        # 获得编号为1的英雄
        hero=HeroInfo.objects.get(pk=1)
        # 获得hero英雄出自的图书
        bookout=hero.hbook
        # print(bookout.btitle)
     
    3 、自关联
    对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构。
     
    (1)定义自关联的模型类   models.py中
    # 地区模型类  存储省 市 区县
    class AreaInfo(models.Model):
        atitle=models.CharField(max_length=30)
        # 关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的
        aParent=models.ForeignKey("self",null=True,blank=True)
     
    (2)定义查询视图   views.py中
    # 查询广州信息
    def area(request):
        area=AreaInfo.objects.get(atitle="广州市")
        return render(request,'booktest/area.html',{'area':area})
     
    (3)定义模板    html文件中
    模板中的数据操作,完全是面向对象的思想。
    <html>
    <head>
        <title>地区</title>
    </head>
    <body>
    当前地区:{{ area.atitle }}
    <hr/>
    上级地区:{{ area.aParent.atitle }}
    <hr/>
    下级地区:
    <ul>
        {% for a in area.areainfo_set.all %}
        <li>{{ a.atitle }}</li>
        {% endfor %}
    </ul>
    </body>
    </html>
     
    (三)对模型类、模型实例、外键自动添加字段的理解
    模型类,相当于一张表(BookInfo类对应bookinfo表、HeroInfo对应heroinfo表)
    模型实例、模型对象,相当于表中的一条记录(又称对象)(book、hero)
    外键自动添加字段(属性、也称成员),如因为外键hbook字段(属性)调用外键方法,导致在另一张表BookInfo中生成类成员heroinfo(供表用)、对象成员heroinfo_set(供一条记录用)
     
     
    在视图(views.py)中体会使用:
     

     
    在模板(*.html)中体会使用:
     
     
     
     
     
  • 相关阅读:
    Beta冲刺置顶随笔
    Beta总结
    用户试用与调查报告
    Beta冲刺第七天
    Beta冲刺第六天
    Beta冲刺第五天
    Beta冲刺第四天
    Beta冲刺第三天
    Beta冲刺第二天
    爬虫基本操作
  • 原文地址:https://www.cnblogs.com/andy9468/p/8784939.html
Copyright © 2020-2023  润新知