美文网首页
ORM联表查询

ORM联表查询

作者: 干掉楼上 | 来源:发表于2021-03-14 22:50 被阅读0次

    双下划线的使用

    from django.db import models
    
    # Create your models here.
    class Student(models.Model):
        s_id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=64)
        age = models.IntegerField(null=True)
        birth = models.DateField(auto_now_add=True)
    
        def __str__(self):
            return self.name
    
        class Meta:
            db_table = 'Student'
    

    1、查询s_id大于等于3的数据

    # 查询s_id大于3的数据
    print(stu_obj.filter(s_id__gt=3).values()) gt: gerater than
    # 查询s_id大于等于3的数据
    print(stu_obj.filter(s_id__gte=3).values()) e: equal gerater than
    

    2、查询s_id小于等于3的数据

    # 查询s_id小于3的数据
    print(stu_obj.filter(s_id__lt=3).values())  lt: less than
    # 查询s_id小于等于3的数据
    print(stu_obj.filter(s_id__lte=3).values())
    

    3、查询s_id 为2-4的数据range(范围)

    # 包含s_id 2 和 4
    print(stu_obj.filter(s_id__range=[2, 4]).values())
    

    4、成员方法in,查询s_id 为1和5的数据

    # 查询s_id是否存在数据表中,存在则返回QuerySet对象列表,否则返回空
    print(stu_obj.filter(s_id__in=[2, 4, 5]).values())
    

    5、contains包含、模糊查询、完全匹配

    # 查询name中包含 '马' 的所有数据 相当于mysql中额like
    print(stu_obj.filter(name__contains='马').values())
    

    6、contains包含、模糊查询、忽略大小写 (存在问题)

    print(stu_obj.filter(name__icontains='lopo'))
    

    7、以某个字符开头

    print(stu_obj.filter(name__startswith='马').values())
    

    8、以某个字符结尾

    print(stu_obj.filter(name__endswith='2').values())
    

    9、以某个字符开头或结尾、忽略大小写

    print(stu_obj.filter(name__iendswith='q'))
    print(stu_obj.filter(name__istartswith='q'))
    

    10、date查询

    # 单独查询年份或月份
    print(stu_obj.filter(birth__year=2019))
    # 查询年月
    print(stu_obj.filter(birth__year=2019, birth__month=11))
    # 查询年月日
    print(stu_obj.filter(birth__year=2019, birth__month=11, birth__day=20))
    

    11、查询null

    # 查询所有为null的数据
    print(stu_obj.filter(age__isnull=True))
    # 查询所有非null的数据
    print(stu_obj.filter(age__isnull=False))
    

    外键操作

    classStudent(models.Model):
        # 设置外键
        classes = models.ForeignKey('Classes', on_delete=models.DO_NOTHING, null=True)
    
    class Classes(models.Model):
        c_id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
    
        class Meta:
            db_table = 'classes'
    

    基于对象查询

    正向查询(通过一张存在ForeignKey字段的表查询其他表为正向查询)

    1、通过学生名获取对应班级名

    # 获取到该学生对应的班级对象, 关系管理对象
    print(models.Student.objects.get(pk=1).classes)
    # 通过这个对象可以获取班级表中的数据
    print(models.Student.objects.get(pk=1).classes.c_id)
    print(models.Student.objects.get(pk=1).classes.name)
    

    2、通过班级获取当前班级对应的学生信息

    反向查询

    cla_obj = models.Classes.objects
    
    print(cla_obj.get(pk=2).name)
    # 获取当前班级对象对应的所有学生
    print(cla_obj.get(pk=2).student_set.all())
    

    3、使用 related_name,基于对象进行反向查询

    classes = models.ForeignKey('Classes', on_delete=models.CASCADE, related_name='students')
    # 指定related_name后student_set则无法使用
    

    基于字段查询

    # 通过班级名字查询所有学生
    stu_obj = models.Student.objects
    # classes为外键字段名
    print(stu_obj.filter(classes__name='java').all())
    

    使用包含

    print(stu_obj.filter(classes__name__contains='java').all())
    

    不指定related_name 通过学生名字查询对应的班级

    print(cla_obj.filter(students__name='刘德华').values())
    

    指定related_name, 指定related_name后无法使用类名

    print(cla_obj.filter(students__name='刘德华').values())
    

    指定related_query_name后无法使用related_name,基于字段的反向查询

    classes = models.ForeignKey('Classes', on_delete=models.CASCADE, related_name='students', related_query_name='student')
    print(cla_obj.filter(student__name='刘德华').values())
    

    外键关系管理

    1、set修改关联关系(外键中关系管理对象 必须传入对象)

    修改学生id为3的课程为1

    models.ClassesModel.objects.get(pk=1).students.set(models.StudentModel.objects.filter(s_id__in=[1, 2, 3]))
    

    2、通过班级创建学生并建立关联关系

    cls_obj = models.Classes.objects
    cls_obj.get(pk=1).students.create(name='张柏芝')
    

    3、删除班级和学生的关联关系

    models.Classes.objects.get(pk=2).students.clear()
    
    models.Classes.objects.get(pk=2).students.set(models.Student.objects.filter(s_id__in=[2, 4, 5, 7]))
    

    3、建立班级和学生的关联关系

    models.ClassesModel.objects.get(pk=2).students.set(models.StudentModel.objects.filter(s_id__in=[1, 2, 3]))
    

    级联删除

    级联删除选项

    Django模型中的on_delete属性具有如下选项:

    CASCADE

    级联删除,也就是被引用的实体被删除后,相关的记录信息都会被删除。

    PROTECT(保护)

    阻止删除被引用的实体,除非先把所有引用的记录删除。抛出ProtectedError类

    SET_NULL

    把字段设置成null,但是必须允许为null的情况下。

    SET_DEFAULT

    把字段设置成默认值,这时这个字段必须设置了默认值。

    SET

    可以传递一个函数给SET()方法作为参数,当字段引用的记录被删除后,此字段的值由给定的方法决定。

    DO_NOTHING

    什么都不做,保持之前的值。如果你的数据库后端设置了外键约束,那么就抛出一个IntegrityError。

    多对多关系

    多对多字段查询

    class Course(models.Model):
        r_id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        student = models.ManyToManyField('Student')
    
        class Meta:
            db_table = 'course'
    
        def __str__(self):
            return f"{self.r_id}--{self.name}"
    

    基于对象

    1、通过课程对象获取当前课程的所有学生

    cou_obj = models.Course.objects.get(pk=1).student.all()
    

    2、通过学生对象获取当前学生的所有课程

    print(models.Student.objects.get(pk=1).course_set.all())
    

    3、使用related_name

    基于字段

    3、通过学生名字段获取所有当前学生的课程

    print(models.Course.objects.filter(student__name='刘德华'))
    

    5、通过课程名字段获取当前课程的所有学生

    print(models.Student.objects.filter(course__name='java'))
    

    6、通过课程名字段获取当前课程的所有学生(related_query_name)

    student = models.ManyToManyField('Student', related_name='courses', related_query_name='course')
    
    print(models.Student.objects.filter(course__name='java'))
    

    对多对关系管理

    1、修改关系

    修改学生对应的课程

    models.Student.objects.get(pk=1).courses.set([2, 4])
    

    通过对象的方式

    models.Student.objects.get(pk=1).courses.set([*models.Course.objects.filter(r_id__in=[1, 3])])
    

    2、新增关系

    # 新增学生和课程的关系
    # 先课程id再学生id
    models.Student.objects.get(pk=1).courses.add(1)
    

    通过对象的方式

    models.Student.objects.get(pk=1).courses.add(*models.Course.objects.filter(r_id__in=[1, 2]))
    

    3、删除关系

    models.Student.objects.get(pk=1).courses.remove(1, 2)
    

    4、清空关系

    models.Student.objects.get(pk=1).courses.clear()
    

    5、通过课程创建一个学生并建立关联关系

    models.Course.objects.get(name='java').student.create(classes_id=2, name='梁静茹')
    

    6、通过学生创建一个课程并建立关联关系

    models.Student.objects.get(s_id=1).courses.create(name='JS')
    

    相关文章

      网友评论

          本文标题:ORM联表查询

          本文链接:https://www.haomeiwen.com/subject/zkrpbktx.html