Django ORM

Django ORM  一对多,多对多关系  的增删改查

ORM一对多,多对多关系

用到一对多,也可以应用到多对多

一对多的增删改查

跨表的话需要双下划线去跨字段 sch__name

一对多的查询

_class = 'abc'

obj = models.Class.objects.all()   # --> [queryset,queryset]


obj1 = models.Class.objects.filter(name=_class)  #  queryset
for i in obj: print (i.name, i.sch.name) # 跨表查询 obj2 = models.Class.objects.filter(name=_class).first() print (obj2.name, obj2.sch.name) for i in obj.user.all(): print (i.name, i.username) #跨表查询,将里面的所有用户全部打印出来 

一对多创建

创建
obj= models.School.ojbect.filter(name='aaa_ban')   
      #先创建了 学校的班级
class_obj = models.Class.ojbect.create(name='aaa',sch=ojb)  
      #然后再使用这个班级去创建新的用户

print (class_obj.sch.name) #通过 sch 跨表,点出来创建新学校的名字 删除 obj = models.Class.objects.filter(name='aaa_ban').delete() # 选择相应的名字字段,然后删除 修改 models.Class.objects.filter(sch__name='aaa_ban').update(name='10_python') # 跨表字段 需要加双下划线 sch__name #更新的是Class 中的 name字段信息。更新成 '10_python' 删除 models.Class.objects.filter(sch__name='10_python').delete() # 跨表字段删除,在class里面的10_python ,全部删除 

多对多的操作

正向跨表去操作数据
class 这个数据表里有这个 user 字段,用了他的一对多关系,通过这个user字段拿到它的所有数据,这里的所有数据就是UserInfo里的数据。

这样就可以实现正向跨到另一张 UserInfo 表里去。

查看    

ojb = models.Class.objects.filter(name='aaa').first()  
       #因为是一对多关系,所以拿到了可能是多个数据

for i in ojb.user.all()     
       # 用了他的一对多关系,通过他的user字段里的拿到它的所有数据,就可以这个数据全部循环出来 print (i.name, i.username) #这里是的 UserInfo 的user数据 

增 删 改
add()#增加
remove()#删除表 ,只删一条数据
clear() #清空表 , 把所有关系的表全部清空

修改需要通过以上的方法协同使用达到目标

第一种,使用创建UserInfo的用户信息的ID再来添加多对多关系的增加
使用创建的时候的ID然后再加入多对多的关系里去

obj_c = models.Class.objects.filter(name='aaa').first()

user_obj = models.Class.objects.create(name='test_many',username='test_to_test') 
           #先创建这个用户信息,再使用它的ID添加多对多关系里去
user_obj.id   # 就是这个对象ID了 obj_c.user.add(user_obj.id) #这里的 .user 很重要,他是跨表的关键 。 #add(默认是数字),是增加关系的字段的ID。但不止是数字 

第二种 使用现有的用户信息,根据filter查询找到他的ID再进行添加多对多关系

obj_c = models.Class.objects.filter(name='aaa').first()   #第一次查找 的条件

user_obj = models.UserInfo.objects.filter(name='abc')   #第二次查找  的条件

obj_c.user.add(*user_obj)  # 针对第三张表去增加。 要是用这个user_obj 对象 需要增加* 

删除
和增加类似 ,只需要把add() 换成remove 即可

obj_c = models.Class.objects.filter(name='aaa').first()   #第一次查找 的条件

user_obj = models.UserInfo.objects.filter(name='abc')   #第二次查找  的条件

obj_c.user.remove(*user_obj)  # 针对第三章表去删除。 要是用这个user_obj 对象 需要增加* 
 many to many  多对多关系 删除 -- clear  清空多对多关系表和对应关系的数据
obj_s = models.Class.objects.filter(name='bbb_ban').first()  
     # 针对多对多关系,将这个字段的内容的所有多对多关系全部清空。

user_obj = models.UserInfo.objects.filter(name='baba')

obj_s.user.clear()

修改
先 clear 后 add
obj_c = models.Class.objects.filter(name='aaa').first() #第一次查找的条件。针对多对多关系,将这个字段的内容的所有多对多关系

全部清空。

user_obj = models.UserInfo.objects.filter(name='abc') #第二次查找的条件。只要有一个符合多对多关系的条件就行

obj_c.user.clear() # 针对第三章表去增加。 要是用这个user_obj 对象 需要增加*

obj_c.user.add(*user_obj) # 先清空再添加关系!

反向跨表操作
已知的表去跨表,根据类的名字的小写去找到所需的字段

反向查询

user_obj = models.UserInfo.objects.filter(name='abc').first()   # 先把UserInfo的条件写出查询来

for i in user_obj.class_set.all():   
    print (i.name) # user_obj 通过这个表的类的名字的小写 ,点出来类的名字的小写 .class_set.all() 拿到里面所有的数据 # 如果数据库里加了 related_name='clauser' 就可以不用set了,直接 user_obj.clauser.all() 也可以实现 # related_name : 关联对象反向引用描述符。 

反向 增加

user_obj = models.UserInfo.objects.filter(name='abc').first()   
    #先通过已知的UserInfo表里的字段,查询得到对象
obj_c = models.Class.objects.filter(name='bbb')    #再 查询一个班级的

user_obj.class_set.add(*obj_c)  
     # 把这两个查询的结果添加进 多对多的关系表里。这里可以写 obj_c.id 或者 *obj_c 

反向删除 -- remove

user_obj = models.UserInfo.objects.filter(name='abc').first() 
    #先通过已知的UserInfo表里的字段,查询得到对象
obj_c = models.Class.objects.filter(name='bbb')    #再 查询一个班级的

user_obj.class_set.remove(*obj_c)   
    # 把这两个查询的结果添加进 多对多的关系表里。这里可以写 obj_c.id 或者 *obj_c 

反向删除 -- clear

user_obj = models.UserInfo.objects.filter(name='abc').first()  
      #先通过已知的UserInfo表里的字段,查询得到对象
obj_c = models.Class.objects.filter(name='bbb')    #再 查询一个班级的

user_obj.class_set.clear()   
     # 把这两个查询的结果添加进 多对多的关系表里。这里可以写 obj_c.id 或者 *obj_c

Django 条件查询

ORM高级—双下划线 条件查询

双下划线(__)之单表条件查询

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

models.Tb1.objects.filter(id__in=[11, 22, 33])   
# 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  
# 匹配ID 在列表中的值 或者可以是 not in #filter的反序 exclude,即取反

models.Tb1.objects.filter(name__contains="ven")    #查询包含的关键字 models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感 models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and startswith,istartswith, endswith, iendswith, istartswith #查询以什么开头 endswith #查询以什么结尾的 

惰性机制(迭代/切片) F查询和Q查询

obj = models.UserInfo.all()    #queryset

for i in obj[1:3]: #切片 print (i.name) F 查询 from django.db.models import F models.UserInfo.objects.update(password=F('password')+1000) #对这个字段的数字加1000,如果不是int则会跳过 Q 查询 from django.db.models improt Q obj = models.UserInfo.objects.filter(Q(username__startswith='t')|Q(username__endswith='c')) #或的关系 obj = models.UserInfo.objects.filter(Q(username__startswith='t'),Q(username__endswith='c')) #与的关系 obj = models.UserInfo.objects.filter(Q(username='xxx') | Q(password='xxx')) # 或的关系 for i in obj: print (i.name) # 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)) ) 

反向查找的related_name
使用related_name='自定义名',反向查找的时候不用再用 _set 来反向查找

#没使用 related_name='自定义名' 
obj_s = models.UserInfo.objects.filter(name='aaa').first()
   for i in obj_s.class_set.all():
         print (i.name) #没使用 related_name='clauser' obj_s = models.UserInfo.objects.filter(name='aaa').first() for i in obj_s.clauser.all(): print (i.name) 

 

转载于:https://www.cnblogs.com/huidou/p/10757852.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值