关于django的ORM补充
程序员文章站
2024-02-10 23:41:04
...
# 数据库外键字段设置的参数
# on_delete参数在2.0以后的django版本中都必须写,以前版本默认是CASCADE
on_delete=models.SET_NULL,db_constraint=False # 若关联字段删除,则该字段置为null
on_delete=models.DO_NOTHING # 关联字段删除,自己不做任何事
on_delete=models.CASCADE # 级联删除
on_delete=models.SET_DEFAULT,db_constraint=False,default=Null # 关联字段删除后,将该字段置为默认值
'''多对多关系的表不需要设置on_delete参数,但是可以断开关联'''
# 一般外键关联的字段在删除时会报错,无法删除,则加入以下参数,切断表之间的关联,但是仍然可以用ORM的多表查询语法查到数据
db_constraint=False
# 以下字段的作用:我们之前一对多外键字段在反查时,关联字段不在自己表里的表需要通过:表名_set 的方式才能拿到,而设置了这个参数,就可以直接通过设置的名字拿到数据
related_name='coursechapters'
例:
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=64, unique=True, verbose_name="学生名")
class StudentDetail(models.Model):
student = models.OneToOneField(to='Student', on_delete=models.SET_DEFAULT, db_constraint=False, default=10)
info = models.CharField(max_length=64, verbose_name="学生简介")
# 在测试的时候,外键关联需要先插入Student表数据
print(stu.studentdetail.info) # 虽然取消了关联,但是仍然可以正常拿到数据
# 开始没有设置:db_constraint=False,直接删除Student表中的数据时,由于在StudentDetail表中有关联,所以无法删除。然后给外键字段设置这个后,可以删除并做出相应的设置的动作:on_delete=动作
stu = models.Student.objects.get(name='张三')
stu.delete() # 删除Student表中的数据后,对应的StudentDetail的外键字段变为默认值10了
深度跨表查询
# 我们在序列化数据的时候,从表里拿数据,如果是外键字段关联的数据,一般是通过跨表点出来查询。或者可以将另一张表的数据也序列化,然后在用到的序列化类里调用。根据不同的需求,返回不同的接口
"""
# 通过序列化层完成
# 针对一个数据表的不同需求(字段个数 | 字段深度),可以提供多个接口
class CourseModelSerializer(ModelSerializer):
class Meta:
model = models.Course
fields = ['name', 'students']
class TeacherModelSerializer(ModelSerializer):
class Meta:
model = models.Teacher
fields = '__all__' # 这里拿到了teacher的所有字段,有些是不需要的
class CourseDetailModelSerializer(ModelSerializer):
teacher = TeacherModelSerializer()
class Meta:
model = models.Course
fields = ['name', 'students', 'teacher', 'price']
"""
# 其实我们可以在models的类中定义一些方法,用于跨表查询,拿到我们想要的数据
@property
def teacher_name(self):
"""返回老师姓名"""
return self.teacher.name
@property
def section_list(self):
"""课程列表的推荐课时"""
# 获取当前课程所有章节
coursechapter_list = self.coursechapters.filter(is_show=True, is_delete=False).order_by('orders')
# 通过循环章节,获取所有课时,只返回4条数据
data_list = []
for coursechapter in coursechapter_list:
coursesection_list = coursechapter.coursesections.filter(is_show=True, is_delete=False).order_by('orders')
for coursesection in coursesection_list:
if len(data_list) >= 4:
break
data_list.append(({
'id': coursesection.id,
'name': coursesection.name,
'free_trail': coursesection.free_trail
}))
return data_list
# 多对多表(book和author,在book表中如下寻找)
@property
def author_list(self):
res = []
authors = self.authors.all()
for author in authors:
res.append(author.name)
return res
# 然后在序列化类的字段中使用
fields = ['teacher_name','section_list']