ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

day8关联对象操作于多表查询 有问题待解决

2022-06-15 10:35:21  阅读:121  来源: 互联网

标签:ch 多表 name day8 s1 查询 objects Student 模型


一对多

正向(定义外键的一方)

一个模型如果有一个外键字段,通过这个模型对外键的操作叫做正向

更新

# 创建一个渠道
ch = Channel(name='小红书')
ch.save()
# 第一种通过属性方式赋值
s1 = Student.objects.get(name='tom')
s1.channel = ch
s1.save()
# 第二种通过主键的赋值方式
s1 = Student.objects.get(name="李大毛")
ch = Channel.objects.get(name="小红书")
s1.channel_id = ch.id
s1.save()

:只有当返回 <Student: 中欧>才有save方法,返回查询集<QuerySet [<Channel: 京东>, <Channel: 小红书>]>没有save方法

 

删除

如果一个外键字段有null=True的属性,我们可以指定外键字段=None来删除关系,没指定null=True的不能删除

s1.channel = None
s1.save()

# 查询所有百度渠道的学生
# 正向查询
Student.objects.filter(channel__name="百度")  # 跨表查询   表名__属性名
# 反向查询
ch = Channel.objects.get(name="抖音")
ch.student_set.all()  # student_set是默认属性名,可以自定义更改
ch.students.all()  #  student_set更改成students后的查询

 

反向

一个模型如果被另一个模型外键关联,通过这个模型对关联它的模型进行操作叫做反向

模型A外键关联模型B,那么模型B的实例可以返回模型A的一个管理器

Student模型外键关联Channel模型,那么Channel模型的实例,默认情况下有一个属性student_set,它是一个student模型的管理器,这个属性名的规则是:模型名小写_set

注意:模型名小写_set,这个属性名可以改

通过channel模型创建student模型的数据

ch.students.create(name="殷芝", age=25, sex=1)

 增加多条数据

# 先使用切片查询出多条数据,然后使用add添加
s1,s2,s3 = Student.objects.all()[:3]
ch.students.add(s1, s2, s3)

删除

1、从相关对象中移除指定的对象

# 从抖音删除学生1,2
ch.students.remove(s1, s2)

2、从相关对象中删除所有的对象

# 删除抖音所有学生
ch.students.clear()

 改

替换对象

# 将s1,s2学生的渠道修改为抖音
ch = Channel.objects.get(name="抖音")
s1, s2 = Student.objects.all()[:2]
ch.studens.set([s1,s2])

差所有

# 小红书渠道的所有学生
ch = Channel.objects.get(name="小红书")
ch.studens.all()

 

条件查询

# 查询抖音渠道下,叫tom的学生
ch = Channel.objects.get(name="抖音")
ch.students.filter(name="tom")

 

注意:默认的管理器名字(student_set)可以更改,通过在外键字段上添加一个related_name的选项,可以修改默认管理器名字

class Student(models.Mode):
    ...
    channel = models.ForeignKey('Channel', on_delete=models.SET_NULL, null=True, verbose_name='渠道', help_text='渠道来源', related_name='students')

 

一对一

正向(定义onetoone字段的一方)

学生详情模型操作学生模型

s1 = Student.objects.get(name="李大毛")
d1 = StudentDetail(city="深圳", company="跨越")
# 属性赋值
d1.student = s1
d1.save()
# id赋值
d1.student_id = s1_id
d1.save()

反向  有问题

学生模型操作,学生详情模型

# 给学生s2添加学生详情
d2 = StudentDetail(city="深圳", company="大疆")
d2.save()
s1 = Student.objects.get(name="王玉")
s1.studentdetail = d2
s1.save()

 

和一对多的区别:

反向模型实例上的字段不再是管理器,而是一个对象。并且字段名就是模型的小写

 

多对多(定义manytomany的一方)

多对多模型两端都可以获得另一端的管理器,原理类似,一对多

添加报名记录

# 给学生添加c1,c2课程
c1, c2 = Course.objects.all()[0:2]
s1 = Student.objects.get(name="王玉")
s1.course_set.add(c1, c2)
# 给课程c1添加两名学生s1,s2
c1 = Course.objects.get(name="自动化测试")
s1, s2 = Student.objects.all()[8:10]
c1.students.add(s1, s2)

指定了第三表,还可以通过第三张表象一对多关系一样操作:

# 1. 创建一条报名记录,s1学生报名了c1这个课
s1 = Student.objects.get(name="李云龙")
c1 = Course.objects.get(name="自动化测试")
e1 = Entry()
e1.student = s1
e1.course = c1
e1.save()

 

# 想查询所有报名了c1课程的学生
c1.students.all()
# 想查询s1学生报名的所有的课程
s1.course_set.all()

跨表查询

在django的ORM中要跨表,只需要使用模型的相关字段名,并以双下划线分隔,直到你想要的字段为止

查询男生都报名了什么课程

Course.objects.filter(students__sex=1).distinct()

例如查询所有报名了python课程的学员

Student.objects.filter(course__name__contains='python')

查询,报名了python课程的百度渠道的学员

Student.objects.filter(course__name__contains='python', channel__name='百度')

查询,百度渠道的所有的订单

Entry.objects.filter(student__channel__name='百度')

执行原生SQL

1. 执行原生查询并返回模型实例

在管理器上调用raw()方法,用于执行远程SQL查询,返回模型实例:

Student.objects.raw('select * from tb_student where id=%s', params=(1,))

执行它会返回一个RawQuerySet,实例,可以迭代获取对象

for stu in Student.objects.raw('select * from tb_student where id=%s', params=(2,)):
	print(stu)

2. 直接执行自定义的SQL

from django.db import connection
def my_custom_sql():
	with connection.cursor() as cursor:
		cursor.execute('select * from tb_student where id=%s', [2])
		row = cursor.fetchone()
	return row

它返回的就是原始数据

标签:ch,多表,name,day8,s1,查询,objects,Student,模型
来源: https://www.cnblogs.com/junhao86/p/16103974.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有