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.多对多

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

 

 

 

 

万般皆下品,唯有读书高!
原文地址:https://www.cnblogs.com/s686zhou/p/11707894.html