欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于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']