Django的orm练习---多表查询

表关系如下

表结构 :

from django.db import models

# Create your models here.

# 多对多----->>>老师和班级
# 一对多----->>>学生和班级 : 一个班级可以有多个学生----学生设置主键
# 老师和课程 : 一个老师可以教多门课程----课程设置主键
#
# 一对一---->>>>班级和年级 : 一个班级对应一个年级
#
# 成绩表----学生 : 一对多. 一个学生多个成绩 /
# 成绩表----课程 : 一对多 # 学生
class Student(models.Model):
sid=models.AutoField(primary_key=True)
sname=models.CharField(max_length=32)
gender=models.CharField(max_length=32)
class_id=models.ForeignKey(to="Class",on_delete=models.CASCADE) # 班级
class Class(models.Model):
cid=models.AutoField(primary_key=True)
caption=models.CharField(max_length=32)
grade=models.ForeignKey(to="Class_grade",on_delete=models.CASCADE)
teachers=models.ManyToManyField(to="Teacher") # 年级
class Class_grade(models.Model):
gid=models.AutoField(primary_key=True)
gname=models.CharField(max_length=32) # 课程
class Course(models.Model):
cid=models.AutoField(primary_key=True)
cname=models.CharField(max_length=32)
teacher=models.ForeignKey(to="Teacher",on_delete=models.CASCADE) # 老师
class Teacher(models.Model):
tid=models.AutoField(primary_key=True)
tname=models.CharField(max_length=32) #成绩
class Score(models.Model):
sid=models.AutoField(primary_key=True)
student=models.ForeignKey(to="Student",on_delete=models.CASCADE)
course=models.ForeignKey(to="Course",on_delete=models.CASCADE)
score=models.IntegerField()

习题 :

# 1、自行创建测试数据;
# 2、查询学生总人数;
# 3、查询“生物”课程和“物理”课程成绩都及格的学生id和姓名;
# 4、查询每个年级的班级数,取出班级数最多的前三个年级;
# 5、查询平均成绩最高的学生的id和姓名以及平均成绩;
# 6、查询每个年级的学生人数;
# 7、查询每位学生的学号,姓名, 平均成绩;
# 8、查询学生编号为“2”的学生的姓名、该学生成绩最高的课程名及分数;
# 9、查询姓“李”的老师的个数和所带班级数;
# 10、查询班级数小于5的年级id和年级名;
# 11、查询教过课程超过2门的老师的id和姓名;
# 12、查询学过编号“1”课程和编号“2”课程的同学的学号、姓名;
# 13、查询所带班级数最多的老师id和姓名;
# 14、查询有课程成绩小于60分的同学的学号、姓名;
# 15、查询男生、女生的人数,按倒序排列;
# 16、 查询各个课程及相应的选修人数;
# 17、 查询同时选修了物理课和生物课的学生id和姓名;
# 18、 检索“3”课程分数小于60,按分数降序排列的同学学号;
# 19、 查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
# 20、 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;

答案 :

from django.shortcuts import render,HttpResponse,redirect

from app01.models import Class,Course,Teacher,Student,Score,Class_grade

from django.db.models import F, Q

from django.db.models import Avg,Max,Sum,Min,Count

# Create your views here.

# values.annotate() : 按字段分组
# annotate() : 按id,name...分组,属于一列是一组 def query(request): # 2 . 查询学生总人数
ret=Student.objects.count()
print("------>",ret) # {'c': 3} # 3 . 查询“生物”课程和“物理”课程成绩都及格的学生id和姓名;
ret = Student.objects.filter(score__course__cid=3,score__score__gt=59).filter(score__course__cid=1,score__score__gt=59).values("sname", "sid")
print("----------------", ret) # 先去筛选选课在生物和物理之间的,并且创建大于60的学生id,在分组查看选课数,然后筛选选课数等于2的
ret=Score.objects.filter(course__cname__in=["生物","物理"],score__gt=60).values("student__tid").annotate(c=Count("course")).filter(c=2) # 4.查询每个年级的班级数,取出班级数最多的前三个年级;
ret=Score.objects.values("student").annotate(avg_score=Avg("score")).order_by("-avg_score").values("student__sname","student__pk","avg_score")[0]
print(ret) ret=Class.objects.values("grade__gname").annotate(c=Count("caption")).order_by("-c")[:3]
print("------>",ret) # 5.查询平均成绩最高的学生的id和姓名以及平均成绩;
ret=Grade.objects.annotate(c=Count("klass__student__pk")).values("gname","c")
print(ret) ret=Student.objects.values("sid","sname").annotate(scoreAvg = Avg("score__score")).order_by("-scoreAvg")[:1]
print("------>", ret) # 6.查询每个年级的学生人数;
ret=Student.objects.values("sid","sname").annotate(avg_score=Avg("score__score"))
print(ret) ret=Student.objects.annotate(avg_score=Avg("score__score")).values("sid","sname","avg_score") ret=Class.objects.values("grade__gname").annotate(c=Count("student"))
print("-------->",ret) # 7 . 查询每位学生的学号,姓名,平均成绩;
ret=Student.objects.values("sid","sname").annotate(scoreAvg=Avg("score__score"))
print("-------->", ret) ret=Score.objects.filter(student__pk=2).order_by("-score").values("student__sname","course__cname","score")[0]
print(ret) # 8、查询学生编号为“2”的学生的姓名、该学生成绩最高的课程名及分数;
ret=Student.objects.filter(sid="2").annotate(scoreMax=Max("score__score")).order_by('-scoreMax')[0:1].values("sname","score__course__cname","scoreMax")
ret2=Student.objects.filter(sid="2").values("score__course").order_by("-score__score").values("sname","score__course__cname","score__score")[:1]
print("-------->", ret)
print("-------->", ret2) # 9、查询每一个姓“李”的老师所带班级数;;
ret=Teacher.objects.filter(tname__istartswith="李").annotate(c=Count("classes")).values("tname","c")
print(ret) # 10 . 查询班级数小于5的年级id和年级名;
ret=Class_grade.objects.annotate(c=Count("class")).filter(c__lt=2).values("gid","gname")
print("--------", ret) ret=Grade.objects.annotate(c=Count("klass")).filter(c__lt=5).values("pk","gname") # 11 . 查询教过课程超过2门的老师的id和姓名;
ret=Teacher.objects.annotate(c=Count("course")).filter(c__gt=2).values_list("tid","tname")
print("--------", ret) # 12 . 查询学过编号“1”课程和编号“2”课程的同学的学号、姓名; ????????
ret=Student.objects.filter(score__course__cid=1).filter(score__course__cid=2).values("sid","sname")
print("-------",ret) # 13 . 查询所带班级数最多的老师id和姓名;
ret=Teacher.objects.annotate(c=Count("class__cid")).order_by("-c").values("tid","tname","c")[0]
print(">>>>>>>>>>",ret) # 14 . 查询有课程成绩小于60分的同学的学号、姓名;
ret=Student.objects.filter(score__score__lt=60).values("sid","sname","score__sid").distinct() #去重
print("-------",ret) ret=Score.objects.filter(score__lt=60).values("student__sname","student__pk").distinct()
print(ret) # 15 . 查询男生、女生的人数,按倒序排列;
ret=Student.objects.values("gender").annotate(c=Count("gender")).order_by("-c")
print("-------",ret) # 16 . 查询各个课程及相应的选修人数;
ret=Course.objects.annotate(c=Count("score__student")).values("cname","c")
print("-------", ret)
ret=Score.objects.values("course").annotate(c=Count(1)).values("course__cname","c")
print(ret) # 17 . 查询同时选修了物理课和生物课的学生id和姓名;
ret=Student.objects.filter(score__course__cname="物理").filter(score__course__cname="生物").values("sid","sname")
print("------->",ret) # 18 . 检索“3”课程分数小于60,按分数降序排列的同学学号;
ret=Student.objects.filter(Q(score__course__cid=3),Q(score__score__lt=60)).order_by("-score__score").values("sid")
ret=Score.objects.filter(course__cid=3).filter(score__lt=60).order_by("-score").values("student__sid")
print("------->", ret) ret=Score.objects.filter(course_id=3,score__lt=60).order_by("-score").values("student_id") # 19 . 查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
ret=Score.objects.values("course_id").annotate(scoreAvg=Avg("score")).order_by("scoreAvg","-course_id") #可以不用跨表 course_id
print("------->", ret) # 20 . 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
ret=Score.objects.values("course__cid").annotate(scoreMax=Max("score"),scoreMin=Min("score"))
print(">>>>>>>>>>>",ret)
ret=Course.objects.annotate(max_score=Max("score__score"),min_score=Min("score__score")).values("pk","max_score","min_score") return HttpResponse("ok")

Django的orm练习---多表查询的更多相关文章

  1. Django的orm操作之表查询二

    复习 单表查询 # 单表操作 # 增 # 方式1 user_obj=models.User.objects.create(**kwargs) # 之一create # 方式2 user_obj=mod ...

  2. 数据库开发-Django ORM的单表查询

    数据库开发-Django ORM的单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询集 1>.查询集相关概述 查询会返回结果的集,它是django.db.mod ...

  3. ORM的多表查询详述

    ORM的多表查询 ORM最核心与用的最多的地方就是跨表查询了.这里的"跨表查询"分为以下几种:基于对象的跨表查询.基于双下划线的跨表查询.聚合查询.F与Q查询以及分组查询. 下面就 ...

  4. 第五章、Django之模型层----多表查询

    目录 第五章.Django之模型层----多表查询 一.一对多字段增删改查 1.增 2.查 3.改 4. 删除 二.多对多的增删改查 1. 增 2. 改 3. 删 三.ORM跨表查询 四.正反向的概念 ...

  5. Django中ORM系统多表数据操作

    一,多表操作之增删改查 1.在seting.py文件中配置数据库连接信息 2.创建数据库关联关系models.py from django.db import models # Create your ...

  6. Django模型层:多表查询

    一 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关 ...

  7. Python学习(三十四)—— Django之ORM之单表、联表操作

    一.单表查询API汇总 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kw ...

  8. Django之ORM多对多表创建方式,AJAX异步提交,分页器组件等

    MTV与MVC MTV模型: ​ M:模型层(models.py),负责业务对象和数据库关系的映射(ORM) ​ T:模板层(Template),负责如何把页面展示给用户(HTML) ​ V:视图层( ...

  9. django 利用ORM对单表进行增删改查

    牛小妹上周末,一直在尝试如何把数据库的数据弄到界面上.毕竟是新手,搞不出来,文档也看不懂.不过没关系,才刚上大学.今晚我们就来解释下,要把数据搞到界面的第一步.先把数据放到库里,然后再把数据从库里拿出 ...

随机推荐

  1. maven公布jar、aar、war等到中央库(Central Repository)的步骤

    步骤一:注冊账号.申请ticket. 注冊在这里:https://issues.sonatype.org 申请ticket:创建一个issue.注意这里要选OSSRH,且是PROJECT而不是TASK ...

  2. Hibernate_day04--HQL查询

    HQL查询 1 hql:hibernate query language,hibernate提供一种查询语言,hql语言和普通sql很相似,区别:普通sql操作数据库表和字段,hql操作实体类和属性 ...

  3. 剑指 offer set 22 数组中的逆序数

    总结 1. 题目为归并排序的变形, 不过我完全没想到 2. 在归并排序进行字符组 merge 时, 统计逆序数. merge 后, 两个子数组是有序的了, 下次再 merge 的时候就能以 o(n) ...

  4. 剑指 offer set 16 数字在排序数组中出现的次数

    总结 1. Leetcode 上有一道题, 求某一个数字在有序数组中出现的最左位置和最右位置, 而这道题就是那题的变形

  5. weX5如何绑定KO对象

    define(function(require){ var $ = require("jquery"); var justep = require("$UI/system ...

  6. c#基础 第八讲

    static void Main(string[] args) { while (true)//一直循环 { Random r = new Random();//创建随机函数r int[] caipi ...

  7. powerdesigner 修改name时code不修改

    o

  8. Spring的Bean的生命周期以及Bean的后置处理器

    Bean的生命周期: Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务. Spring IOC 容器对 Bean 的生命周期进 ...

  9. C语言实现双链表(带头节点)

    双链表和单链表性质相似只是在多加了一个前指针 1.定义结构体 typedef struct Node{ int data; struct Node *prior; struct Node *next; ...

  10. Ubuntu 16.04修改配置静态IP和DNS

    Ubuntu 16.04修改配置静态IP和DNS 1.修改interfaces 文件 sudo gedit /etc/network/interfaces 2.添加 例如: auto enp0s25 ...