Django ORM表字段关系详解

class UserInfo()				class Type			class Group    class Favor
	name = 					      caption			     caption	    caption
	t = models.Foreignkey							
	g = models.ManyToMany
	f = models.OneToOne

 

一、查:

正向:  obj_list = models.UserInfo.objects.all().values('t__caption','username')返回Queryset列表,每一个元素是对应的字典
       obj_list = models.UserInfo.objects.all().values_list('id','username')返回Queryset列表,每一个元素是对应的元组

双下划线__能无限跨
反向查询:默认小写类名_set.all() 能通过related_name='ssss'修改 obj.ssss.all()
反向跨表:models.Type.objects.all().values('caption','ssss','ssss__name') #ssss默认是id,ssss能双下划线跨表

总结:正向与反向都能__进行跨表查询,反向只要定义related_name即可。只不过主表不一样而已。sss__name t__caption
适用于一对一、一对多和多对多。
正向通过外键字段进行跨表操作,反向通过 类_set或者related_name进行操作 obj.sss.add() obj.sss.all() obj.g.all() obj.g.add()
适用于多对多。一对多没有正向,反向可以obj.sss.all(),列出该类型所有的学生,但没有add()

	1.一对一
		母表查子表(查一个人的爱好)
			①obj.f.caption               ---->favor在一个obj中是表Favor的对象
			②models.Favor.objects.get(UserInfo__name="").caption     	# 反向查子表				
		子表查母表(查这个爱好对应的人)
			①models.Favor.objects.get(caption="").userinfo.name  		# 查名字
			②models.UserInfo.objects.get(f__caption="").name       		# 反向查名字			
	2.一对多
		母表查询外键表(查该用户对应的那一个类型)
			①models.UserInfo.objects.get(name="").t.caption
			②models.Type.objects.get(userInfo__name="").caption   	    # 反向从类型表查该用户的类型
		外键表查询母表(查该用户类型有几个用户)
			①obj=models.Type.objects.get(caption="")   
			 obj.userinfo_set.all()                               		# 与type.userinfo_set.all()一样,拿到的是对象列表
			②models.UserInfo.objects.filter(caption=models.Type.objects.get(caption=""))  
																		# 反向传对象查询
			③简化:models.UserInfo.objects.filter(t__caption='')  		# 外键字段__外表字段,filter,values条件跨表都要__
			④id=models.Type.objects.get(caption="").id 
			 models.UserInfo.objects.filter(t_id=id)
			⑤models.Type.objects.all().values('caption','ssss__name')	# 查所有的用户类型以及对应的用户名字
			
	3.多对多
		查子表(查该用户有几个组)
			①obj=models.UserInfo.objects.get(name="") 
			 obj.g.all()	#对象列表
			②models.Group.objects.filter(userinfo__name="")
		查母表(该组有几个用户)
			①obj=models.Group.objects.get(caption="")
			 obj.userinfo_set.all())		#与一对多类似     obj.sss.all()                   
			②models.UserInfo.objects.filter(caption=models.Group.objects.get(caption=""))
			③models.UserInfo.objects.filter(g__caption="")  #简化
			④id=models.Group.objects.get(caption="").id     #获取id
				models.UserInfo.objects.filter(f=id)) 

 

二、增

	1.一对一
		obj=models.Favor.objects.create(caption="")  
		models.UserInfo.objects.create(f=obj,name="")  
	2.一对多
		①models.UserInfo.objects.create(t=models.Type.objects.get(caption=""),name="")
		②models.UserInfo.objects.create(t_id=models.Type.objects.get(caption="").id,name="")
		③obj=models.UserInfo(t=models.Type.objects.get(caption=""),name="")
			obj.save()
	3.多对多
		正向:
			①obj=models.UserInfo.objects.create(name="")  #如果是已有用户,使用.get()
			 g_obj=models.Type.objects.all() 	# 必须要QuerySet对象(可理解为列表,加*),不一定全部
			 obj.g.add(*g_obj)  				# 这里添加对应关系,将用户和所有组进行关联,
												# 还支持add(2,3,4),add(*[1,2,3,4]),列表要加*
			②obj=models.UserInfo.objects.get(name="")
			 g_obj=models.Group.objects.all()
			 obj.g=g_obj
			 obj.save()      #多了一步save()
		反向:
			obj.ssss.add([1,2])	

三、改

	1.一对一
		f_obj=models.Favor.objects.get(caption="") #.get()等同于.filter().first()
		f_obj.colors="new value"
		f_obj.save()
		models.UserInfo.objects.filter(name="").update(f=f_obj,name="new value") 
		                                             #update(),delete()是QuerySet的方法
	2.一对多
		①models.UserInfo.objects.filter(t__caption="").update(name="")
		②models.Type.objects.filter(t_id=models.Type.objects.get(caption="").id).update(name="")
		③t_obj=models.Type.objects.get(caption="")
		 t_obj.userinfo_set.filter(id__gte=1).update(name="")

	3.多对多
		正向:
			①obj=models.UserInfo.objects.get(name="")
			 g_obj=models.Group.objects.filter(caption__in=["",""])  
								#models默认只能用这种方式得到并集,如需更复杂的过滤逻辑,需使用模块Q
			 obj.g.clear()      #清空组
			 obj.g.add(*g_obj)  #add是追加模式,如果当前有用户组,那么执行后,会额外添加组
								# ojb.g.set([2,3,4])  不加*  set表示全删了加上
			
			②bj=models.UserInfo.objects.get(name="")     #获取到一个值
			 g_obj=models.Group.objects.get(caption="")
			 obj.g.clear()
			 obj.g.add(g_obj)  #此处没有*,区别在于多个数据时要加*
			
		反向:
			①obj=models.UserInfo.objects.get(name="")
			 g_obj=models.Group.objects.get(caption="")
			 g_obj.userinfo_set.add(obj)              #从组表插入用户,多数据要加*
		
			②obj.sss.set()		#清空并新设置,原来已经有就不会先删再增加

  

四、删

	1.一对一
		models.UserInfo.objects.get(name="").delete() #对象和QuerySet都有方法delete()
		models.Favor.objects.filter(caption="").delete()
		
		models.Favor.objects.all().delete() #清空一张表
	2.一对多
		models.UserInfo.objects.get(name="灰裙子").delete() #对象和QuerySet都有方法delete()
		models.Type.objects.filter(t="").delete()
	3.多对多
		正向:
			删除用户的所有组关系
			①obj=models.UserInfo.objects.get(name="")
			 g_obj=models.Group.objects.all()
			 obj.f=''
			 obj.save()
			②obj=models.UserInfo.objects.get(name="")
			 g_obj=models.Group.objects.all()
			 obj.g.remove(*g_obj)			

			③obj=models.UserInfo.objects.get(name="")
			 obj.g.clear()
			删除组的所有用户	
			①obj=models.UserInfo.objects.all()   #all
			 g_obj=models.Group.objects.get(caption="")
			 g_obj.userinfo_set.remove(*obj)

			 ②g_obj=models.Group.objects.get(caption="蓝")
			  g_obj.userinfo_set.clear()	
			删除指定			
			obj.g.remove(2,4)
		反向:
			obj.sss.remove(2,4)

  

 

 

 




posted @ 2018-07-28 15:44  心平万物顺  阅读(162)  评论(0编辑  收藏  举报