08-模型-条件查询

  1. 字段查询

    1. 实现sql中where的功能,调用过滤器filter()、exclude()、get(),下面以filter()为例
    2. 通过“属性名_id”表示外键对应对象的id值
    3. 语法如下
    4. 说明:属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线
      1. 属性名称__比较运算符=值
  2. 条件运算符

    1. exact:表示判等

      1. 例:查询编号为1的图书
        list=BookInfo.books.filter(id__exact=1)
        可简写为:
        list=BookInfo.books.filter(id=1)
        
    2. contains:是否包含

    3. 说明:如果要包含%无需转义,直接写即可

    4. 例:查询书名包含‘传’的图书

      1. list = BookInfo.books.filter(btitle__contains='传')
    5. startswith、endswith:以指定值开头或结尾

    6. 例:查询书名以‘部’结尾的图书

      1. list = BookInfo.books.filter(btitle__endswith='部')
    7. isnull:是否为null

      1. 例:查询书名不为空的图书
        list = BookInfo.books.filter(btitle__isnull=False)
    8. 以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith

    9. in:是否包含在范围内

      1. 例:查询编号为1或3或5的图书
        list = BookInfo.books.filter(pk__in=[1, 3, 5])
    10. gt、gte、lt、lte:大于、大于等于、小于、小于等于

      1. 例:查询编号大于3的图书
        list = BookInfo.books.filter(id__gt=3)
    11. 不等于使用等于的运算符,使用exclude()过滤器
      例:查询编号不等于3的图书
      list = BookInfo.books.exclude(id=3)

    12. 不等查询
      year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算
      例:查询1980年发表的图书
      list = BookInfo.books.filter(bpub_date__year=1980)

    13. 日期查询1

      例:查询1980年1月1日后发表的图书
      list = BookInfo.books.filter(bpub_date__gt=date(1990, 1, 1))

      日期查询2

  3. 关联查询(外连接类似)

    1. Django中也能实现类似于join查询
      语法如下

      1. 关联模型类名小写属性名运算符=值

      2. 如果没有没有“__运算符”部分,表示等于,结果和sql中的inner join相同

        1. 例:查询图书,要求图书中英雄的描述包含‘八’
            list = BookInfo.books.filter(heroinfo__hcontent__contains='八')
        
        1. 例:查询书名为"天龙八部"的所有英雄
            list = HeroInfo.objects.filter(hbook__btitle='天龙八部')
        
    2. F对象

      之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中
      语法如下

      1. F(属性名)
        例:查询阅读量大于等于评论量的图书
      from django.db.models import F
      ...
      list = BookInfo.books.filter(bread__gte=F('bcommet'))
      
      1. 可以在F()对象上使用算数运算
        例:查询阅读量大于2倍评论量的图书
      list = BookInfo.books.filter(bread__gt=F('bcommet') * 2)
      
    3. Q对象

      1. 多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字
      2. 例:查询阅读量大于20,并且编号小于3的图书
        list=BookInfo.books.filter(bread__gt=20,id__lt=3)

        list=BookInfo.books.filter(bread__gt=20).filter(id__lt=3)
    3. 如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符
    4. **Q对象被义在django.db.models中**
        1. 语法如下
            Q(属性名__运算符=值)
            1. 例:查询阅读量大于20的图书,改写为Q对象如下
            from django.db.models import Q
            ...
            list = BookInfo.books.filter(Q(bread__gt=20))
            

        2. Q对象可以使用&、|连接,**&表示逻辑与,|表示逻辑或**
            1. 例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
            list = BookInfo.books.filter(Q(bread__gt=20) | Q(pk__lt=3))
        

    5. Q对象前可以使用~操作符,表示非not
        1. 例:查询编号不等于3的图书
        list = BookInfo.books.filter(~Q(pk=3))
  1. 聚合函数
    1. 使用aggregate()过滤器调用聚合函数
      聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中

      1. 例:查询图书的总阅读量
      from django.db.models import Sum
      ...
      list = BookInfo.books.aggregate(Sum('bread'))
      
    2. 在运行服务器命令行可以看到list的字典结果

    3. 使用count时一般不使用aggregate()过滤器

      1. 例:查询图书总数
        list = BookInfo.books.count()
    4. 在运行服务器命令行可以看到list的结果

  1. 关联查询的练习

    1. 关联的查询
      在定义模型类时,可以指定三种关联关系,最常用的是一对多关系,如本例中的“图书-英雄”就为一对多关系,接下来进入shell练习关系的查询

      python manage.py shell

      1. 查询编号为1的图书
        book=BookInfo.books.get(pk=1)

      2. 获得book图书的所有英雄
        book.heroinfo_set.all()

      3. 获得编号为1的英雄
        hero=HeroInfo.objects.get(pk=1)

      4. 获得hero英雄出自的图书
        hero.hbook

    2. 自关联

      1. 对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以可以设计成一张表,内部的关系字段指向本表的主键,这就是自关联的表结构

      2. 打开booktest/models.py文件,定义AreaInfo类
        说明:关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的

      定义地区模型类,存储省、市、区县信息

      class AreaInfo(models.Model):
          atitle=models.CharField(max_length=30)#名称
          aParent=models.ForeignKey('self',null=True,blank=True)#关系
      
      1. 迁移

        1. python manage.py makemigrations
          python manage.py migrate
      2. 打开mysql命令行,导入数据

        1. source areas.sql
      3. 打开booktest/views.py文件,定义视图area

        from models import AreaInfo
        ...
        #查询广州市的信息
        def area(request):
            area = AreaInfo.objects.get(pk=440100)
            return render(request, 'booktest/area.html', {'area': area})
        
        
      4. 打开booktest/urls.py文件,新建一条url

        urlpatterns = [
            ...
            url(r'^area/$', views.area),
        ]
        
      5. 在templates/booktest目录下,新建area.html文件

        
        
            地区
        
        
        当前地区:{{area.atitle}}
        
        上级地区:{{area.aParent.atitle}}
        下级地区:
          {%for a in area.areainfo_set.all%}
        • {{a.atitle}}
        • {%endfor%}
        1. 运行服务器
          python manage.py runserver
  2. 总结

    1. 修改配置文件使用mysql数据库
    2. 属性类型及选项
    3. 自定义管理器及用途
    4. 查询集和条件查询
    5. 关联

你可能感兴趣的:(08-模型-条件查询)