zoukankan      html  css  js  c++  java
  • django 面试题

    面试题1:migrate怎么判断哪些迁移脚本需要执行:

    他会将代码中的迁移脚本和数据库中django_migrations中的迁移脚本进行对比,如果发现数据库中,没有这个迁移脚本,那么就会执行这个迁移脚本。

    面试题2:migrate做了什么事情:

    1. 将相关的迁移脚本翻译成SQL语句,在数据库中执行这个SQL语句。
    2. 如果这个SQL语句执行没有问题,那么就会将这个迁移脚本的名字记录到django_migrations中。

    面试题3:执行migrate命令的时候报错的解决办法:

    原因:

    执行migrate命令会报错的原因是。数据库的django_migrations表中的迁移版本记录和代码中的迁移脚本不一致导致的。

    解决办法:

    使用–fake参数:

    首先对比数据库中的迁移脚本和代码中的迁移脚本。然后找到哪个不同,之后再使用--fake,将代码中的迁移脚本添加到django_migrations中,但是并不会执行sql语句。这样就可以避免每次执行migrate的时候,都执行一些重复的迁移脚本。

    终极解决方案:

    如果代码中的迁移脚本和数据库中的迁移脚本实在太多,就是搞不清了。那么这时候就可以使用以下终极解决方案: 
    1. 终极解决方案原理:就是将之前的那些迁移脚本都不用了。重新来过。要将出问题的app下的所有模型和数据库中表保持一致,重新映射。 
    2. 将出问题的app下的所有模型,都和数据库中的表保持一致。 
    3. 将出问题的app下的所有迁移脚本文件都删掉。再在django_migrations表中将出问题的app相关的迁移记录都删掉。 
    4. 使用makemigrations,重新将模型生成一个迁移脚本。 
    5. 使用migrate --fake-initial参数,将刚刚生成的迁移脚本,标记为已经完成(因为这些模型相对应的表,其实都已经在数据库中存在了,不需要重复执行了。) 
    6. 可以做其他的映射了。

    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)
    1. 查询姓“李”的老师的个数;

      teacher_nums = Teacher.objects.filter(name__startswith="李").count()
      print(teacher_nums)
      • 1
      • 2
    2. 查询没学过“黄老师”课的同学的id、姓名;

      rows = Student.objects.exclude(score__course__teacher__name="黄老师").values('id','name')
      for row in rows:
      print(row)
    3. 查询学过id为1和2的所有同学的id、姓名;

      rows = Student.objects.filter(score__course__in=[1,2]).distinct().values('id','name')
      for row in rows:
      print(row)
    4. 查询学过“黄老师”所教的所有课的同学的学号、姓名;

      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)
    5. 查询所有课程成绩小于60分的同学的id和姓名;

      students = Student.objects.exclude(score__number__gt=60)
      for student in students:
      print(student)
    6. 查询没有学全所有课的同学的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)
    7. 查询所有学生的姓名、平均分,并且按照平均分从高到低排序;

      students = Student.objects.annotate(avg=Avg("score__number")).order_by("-avg").values('name','avg')
      for student in students:
      print(student)
    8. 查询各科成绩的最高和最低分,以如下形式显示:课程ID,课程名称,最高分,最低分:

      courses = Course.objects.annotate(min=Min("score__number"),max=Max("score__number")).values("id",'name','min','max')
      for course in courses:
      print(course)
    9. 查询每门课程的平均成绩,按照平均成绩进行排序;

      courses = Course.objects.annotate(avg=Avg("score__number")).order_by('avg').values('id','name','avg')
      for course in courses:
      print(course)
    10. 统计总共有多少女生,多少男生;

      rows = Student.objects.aggregate(male_num=Count("gender",filter=Q(gender=1)),female_num=Count("gender",filter=Q(gender=2)))
      print(rows)
    11. 将“黄老师”的每一门课程都在原来的基础之上加5分;

      rows = Score.objects.filter(course__teacher__name='黄老师').update(number=F("number")+5)
      print(rows)
    12. 查询两门以上不及格的同学的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)
    13. 查询每门课的选课人数;

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

     

  • 相关阅读:
    用魔数防范文件上传攻击
    nginx http跳转到https
    tengine安装
    版本标记说明
    nginx基于域名的虚拟主机 反向代理配置实例
    非ROOT用户启动Tomcat
    使用druid连接池的超时回收机制排查连接泄露问题
    Jenkins入门系列之
    centos7 关闭SELINUX 防火墙
    mac安装IE浏览器
  • 原文地址:https://www.cnblogs.com/b02330224/p/9282151.html
Copyright © 2011-2022 走看看