zoukankan      html  css  js  c++  java
  • ORM 单表操作与多表操作

    ORM

    单表操作

    1.创建表

    2.添加记录

    两种方式:1)实例化一个模型类对象    再调用save()方法
    例: obj = Book()   obj.save()
    2) 使用模型表下的objects管理器,用于对表记录增删改查等操作
    例: obj = Book.objects.create()

    3.查询记录

    1)查询API
    Part1. 除了count 其他返回的都是一个记录对象
    get(**kwargs)     注意:如果没有筛选出来就会抛出错误
    first()        
    last()
            count()   注意:返回的是表中所包含的记录对象数量
       
      Part2. 下述方法返回值均是QuerySet类型的对象 这是ORM自定义的一种数据类型
      filter(**kwargs)   筛选包含的
      exclude(**kwargs) 筛选不包含的
      all()    
      order_by(*field) 注意:参数为指定的字段 默认是升序     降序是("-id")
      values(*field)   注意:输出的是列表套字典 <QuerySet [{'id':1,'name':'zzp'},{}]>
      values_list(*field) 注意:输出的是列表套元组 <QuerySet [(1,'zzp'),(),()]>
       
      Part3.
            1.QuerySet对象支持索引操作 QuerySet也就相当于一个大列表
      2.QuerySet 支持链式操作 可以使用多个 Part2中的方法
       
      Part4. 其他查询API
      reverse()   返回值为QuerySet对象 对排序结果取反
      exists()   返回值是布尔值 判断是否存在
      distinct() 从values 或 values_list的返回结果中剔除 重复的记录对象 返回值是QuerySet对象
     
    2)基于双下划线的模糊查询
    filter(id__in=[1,2,3])     select*from book where id in (1,2,3);
    filter(id__gt=3)       >3
    filter(id__lt=3)       <3
    filter(id__gte=3)     >=3
    filter(id__lte=3)     <=3
      filter(id__range=[1,3])       select *from book where id between 1 and 3
      filter(name__contains="IN")   like模糊查询 区分大小写
      filter(name__icontains="in")   like模糊查询 不区分大小写
      filter(name__startwith="西")    
      filter(name__isstartwith="记")
      filter(birth__year=1996)     select*from user where birth between '1996-1-1' and '1996-12-31';
      filter(birth__month=1)
       

    3)F与Q查询
    F查询   查询引用字段的值
    案例: from django.db.modles import F
    Book.objects.all().update(price=F("price")+30)

    Q查询  
      前提:filter(id=1,name='zzp') 这里的筛选中逗号,相当于 and 条件 两者都满足的情况下
      而当我们需要 or 条件是 就可以使用 Q查询
     
      重点: 1.Q对象可以使用 ~ 操作符取反 相当于NOT  
      2.如果有多个过滤条件而且既有or 又有 and时,需要Q对象与关键字参数混用 此时Q对象必须在关 键字参数前面
       
      案例:
      from django.db.models import Q
      User.objects.filter(~Q(id__gt=5) | Q(name='zzp'),salary__lt=100)
       

    4)聚合查询 aggregate
    案例: from django.db.models import Avg,Max,Sum,Min,Max,Count
    res1 = Employee.objects.all().aggregate(nums=Count('id'),Avg('salary'))
    相当于SQL: select count(id) as nums,avg(salary) as salary_avg from employee;
    print(res1) 输出:{'nums':10,'salary_avg':70.16}

    总结: aggregate()返回值是字典类型  
    key默认是由“聚合字段的名称__聚合函数的名称” 就是 avg('salary')
    key 也可以是自定义   就是   nums=Count('id')

    5)分组查询 annotate() 相当于group by 它必须搭配values()使用
      案例1:
          查询每个部门下的员工数
          res = Employee.objects.values('department').annotate(num=Count('id'))
          相当于sql:
          select department,count(id) as num from employee group by department;
          print(res)
          输出:<QuerySet [{'department':'财务部','num':2},{'department':'技术部','num':3}]>
       
      案例2:
      res=Employee.objects.values('department').annotate(num=Count('id')).values('num')
      print(res)
      输出:<QuerySet [{'num':2},{'num':3}]>

    总结: 1.values()在annotate()前表示group by的字段 在后表示取值
    2.filter()在annotate()前表示where条件   在后表示having
       

    4.修改记录

    1)直接修改单条记录对象
    obj = Employee.objects.filter(name='zzp')[0]
    obj.name = 'ZZP'
    obj.save()

    2)修改QuerySet中的所有记录对象
    使用update()方法   该方法返回一个整数型值,表示受影响的记录条数
    queryset_obj = Employee.objects.filter(id__gt=5)
    rows = queryset_obj.update(name='ZZP')

    5.删除记录

    1)直接删除单条记录对象
    obj = Employee.objects.first()
    obj.delete()
    2)删除QuerySet中的所有记录对象
    queryset_obj = Employee.objects.filter(id__gt=5)
    rows = queryset_obj.delete()

     

    多表操作

    1.创建模型 book publish author authordetail 自动生成的第三张表 book_authors

    2.添加,删除,修改记录

    1)添加记录
      1.单表添加 不用说了
      2.多表添加 插入时 会涉及到多张表 所以我们要分三种情况来说
     
        1.一对多:book 与 publish
        方式一:使用publish参数指定关联
        publish_obj = Publish.objects.filter(id=1).first()
        book_obj = Book.objects.create(.....,publish=pubish_obj)
        方式二:使用publish_id参数指定关联
        book_obj = Book.objects.create(.....,publish_id=1)
       
        2.一对一: author与authordetail
            两种方式添加与一对多相同
            方式一:使用author_detail参数指定关联
            方式二:使用author_detail_id参数指定关联
         
        3.多对多:book 与 author
          一共分为三步:
          1.先获取书籍对象
          book_obj = Book.objects.get(id=1)
          2.然后获取作者对象
          author_obj = Author.objects.get(id=1)
          3. 最后通过书籍对象的authors关联的第三张表字段添加
          book_obj.authors.add(author_obj)

    2)删除,修改记录
    remove()
    rose = Author.objects.get(name='rose')
    book_obj2 = Book.objects.get(title='西游记')
    book_obj2.authors.remove(rose)

    clear() 清除所有被关联对象集合
    book_obj2 = Book.objects.get(title='西游记')
    book_obj2.authors.clear()

    set() 需要放置一个列表套对象 [obj1,obj2]
    zzp = Author.objects.get(name='zzp')
    rose = Author.objects.get(name='rose')
     
    book_obj2 = Book.objects.get(title='西游记')
    book_obj2.authors.set([zzp,rose])  

    3.查询记录

    1)基于对象的跨表查询
    1.一对一查询 (Author,AuthorDetail)

    正向查询,按关联字段 author_detail
    需求:查询作者zzp的手机号
    zzp = Author.objects.filter(name='zzp').first()
    print(zzp.author_detail.tel)

          反向查询 按模型名(小写) author
          需求:查询手机号为110的作者名
          tel = AuthorDetail.objects.filter(tel='110').first()
          print(tel.author.name)
           
        2.多对一查询(Book,Publish)
       
        正向查询,按关联字段:publish
        需求:查询西游记的出版社名字
        book_obj = Book.objects.filter(name='西游记').first()
        print(book_obj.pubilsh.name)
       
        反向查询,按模型名(小写)_set book_set
        需求:查询国家出版社出版的所有书籍名称
        publish_obj = Publish.objects.filter(name='国家出版社').first()
        book_objs = publish_obj.book_set.all()
       
        3.多对多查询 (Book,Author) 跟多对一查询一样
        正向查询,按关联字段:authors
       
        反向查询 按模型名(小写)_set   book_set
     


    2)基于双下划线的跨表查询 此查询会被orm识别为join操作
    1.一对一查询(Author,AuthorDetail)

    正向查询,按关联字段+双下划线 author_detail__
    需求:查询作者egon的手机号
    res = Author.objects.filter(name='egon').values('author_detail__tel').first()

    反向查询 表名小写+双下划线   author__
    需求:查询手机号为’110‘的作者名
    res = AuthorDetail.objects.filter(tel='110').values('author__name').first()

    2.一对多

    3.多对多

      总结:都是按照同样的方式查询
      正向:关联字段+双下划线
      反向:表名小写+双下划线
       

     

     

     

     

    万般皆下品,唯有读书高!
  • 相关阅读:
    DB2 SQL1477N问题
    db2 查看表空间使用率
    DB2中的数据类型
    DB2锁机制
    DB2数据库常用命令数据库学习
    DB2 sql报错后查证原因与解决问题的方法
    F. Bakkar In The Army 二分
    On the way to the park Gym
    csu 1552: Friends 二分图 + Miller_Rabin
    Gym
  • 原文地址:https://www.cnblogs.com/s686zhou/p/11707894.html
Copyright © 2011-2022 走看看