1. 程式人生 > >Django面試題系列(2)-ORM實現複雜查詢

Django面試題系列(2)-ORM實現複雜查詢

假設有以下ORM模型:

from django.db import models

class Student(models.Model):
    """學生表"""
    name = models.CharField(max_length=100)
    gender = models.SmallIntegerField()

    class Meta:
        db_table = 'student'

class Course(models.Model):
    """課程表"""
    name = models.CharField(max_length=100)
    teacher = models.ForeignKey("Teacher"
,on_delete=models.SET_NULL,null=True) class Meta: db_table = 'course' class Score(models.Model): """分數表""" student = models.ForeignKey("Student",on_delete=models.CASCADE) course = models.ForeignKey("Course",on_delete=models.CASCADE) number = models.FloatField() class
Meta:
db_table = 'score' class Teacher(models.Model): """老師表""" name = models.CharField(max_length=100) class Meta: db_table = 'teacher'

使用之前學到過的操作實現下面的查詢操作:

  1. 查詢平均成績大於60分的同學的id和平均成績;

  2. 查詢所有同學的id、姓名、選課的數量、總成績;

  3. 查詢姓“李”的老師的個數;

  4. 查詢沒學過“李老師”課的同學的id、姓名;

  5. 查詢學過課程id為1和2的所有同學的id、姓名;

  6. 查詢學過“黃老師”所教的“所有課”的同學的id、姓名;

  7. 查詢所有課程成績小於60分的同學的id和姓名;

  8. 查詢沒有學全所有課的同學的id、姓名;

  9. 查詢所有學生的姓名、平均分,並且按照平均分從高到低排序;

  10. 查詢各科成績的最高和最低分,以如下形式顯示:課程ID,課程名稱,最高分,最低分;

  11. 查詢沒門課程的平均成績,按照平均成績進行排序;

  12. 統計總共有多少女生,多少男生;

  13. 將“黃老師”的每一門課程都在原來的基礎之上加5分;

  14. 查詢兩門以上不及格的同學的id、姓名、以及不及格課程數;

  15. 查詢每門課的選課人數;

參考答案:

  1. 查詢平均成績大於60分的同學的id和平均成績;

    rows = Student.objects.annotate(avg=Avg("score__number")).filter(avg__gte=60).values("id","avg")
    for row in rows:
    print(row)
  2. 查詢所有同學的id、姓名、選課的數、總成績;

    rows = Student.objects.annotate(course_nums=Count("score__course"),total_score=Sum("score__number"))
    .values("id","name","course_nums","total_score")
    for row in rows:
    print(row)
  3. 查詢姓“李”的老師的個數;

    teacher_nums = Teacher.objects.filter(name__startswith="李").count()
    print(teacher_nums)
  4. 查詢沒學過“黃老師”課的同學的id、姓名;

    rows = Student.objects.exclude(score__course__teacher__name="黃老師").values('id','name')
    for row in rows:
    print(row)
  5. 查詢學過id為1和2的所有同學的id、姓名;

    rows = Student.objects.filter(score__course__in=[1,2]).distinct().values('id','name')
    for row in rows:
    print(row)
  6. 查詢學過“黃老師”所教的所有課的同學的學號、姓名;

    rows = Student.objects.annotate(nums=Count("score__course",filter=Q(score__course__teacher__name='黃老師')))
    .filter(nums=Course.objects.filter(teacher__name='黃老師').count()).values('id','name')
    for row in rows:
    print(row)
  7. 查詢所有課程成績小於60分的同學的id和姓名;

    students = Student.objects.exclude(score__number__gt=60)
    for student in students:
    print(student)
  8. 查詢沒有學全所有課的同學的id、姓名;

    students = Student.objects.annotate(num=Count(F("score__course"))).filter(num__lt=Course.objects.count()).values('id','name')
    for student in students:
    print(student)
  9. 查詢所有學生的姓名、平均分,並且按照平均分從高到低排序;

    students = Student.objects.annotate(avg=Avg("score__number")).order_by("-avg").values('name','avg')
    for student in students:
    print(student)
  10. 查詢各科成績的最高和最低分,以如下形式顯示:課程ID,課程名稱,最高分,最低分:

    courses = Course.objects.annotate(min=Min("score__number"),max=Max("score__number")).values("id",'name','min','max')
    for course in courses:
    print(course)
  11. 查詢每門課程的平均成績,按照平均成績進行排序;

    courses = Course.objects.annotate(avg=Avg("score__number")).order_by('avg').values('id','name','avg')
    for course in courses:
    print(course)
  12. 統計總共有多少女生,多少男生;

    rows = Student.objects.aggregate(male_num=Count("gender",filter=Q(gender=1)),female_num=Count("gender",filter=Q(gender=2)))
    print(rows)
  13. 將“黃老師”的每一門課程都在原來的基礎之上加5分;

    rows = Score.objects.filter(course__teacher__name='黃老師').update(number=F("number")+5)
    print(rows)
  14. 查詢兩門以上不及格的同學的id、姓名、以及不及格課程數;

    students = Student.objects.annotate(bad_count=Count("score__number",filter=Q(score__number__lt=60))).filter(bad_count__gte=2).values('id','name','bad_count')
    for student in students:
    print(student)
  15. 查詢每門課的選課人數;

    courses = Course.objects.annotate(student_nums=Count("score__student")).values('id','name','student_nums')
    for course in courses:
    print(course)