zoukankan      html  css  js  c++  java
  • Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)

    Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)

    一、关系表的数据操作

    #为了能方便学习,我们进入项目的idle中去执行我们的操作,通过python  manage.py shell  就能进入当前目录下的IDLE,类似于数据库中的python操作
    
      --- import os #导入os
      ---os.getcwd() #获取当前路径
          '/home/pyvip/TK18_07/py_course/hello_django1'
      ---from movie.models import Department,Student,Course,Stu_Detail #从app目录的models中导入这些类
    #以下是在python shell模式中的代码
    >>> from movie.models import Department,Student,Course,Stu_Detail
    >>> d2 = Department(d_name = '软件学院') #初始化类,添加一条数据,软件学院
    >>> d2.save() #刷入数据库
    #表关联的添加数据的两种方法
    #方法一
    >>> s3 = Student(s_name='小白',department_id=2)
    >>> s3.save()
    #方法二
    >>> s4 = Student(s_name='小黑')
    >>> s4.department = d2
    >>> s4.save()

      需要查询department中id为1的学院下面有几个学生,可以通过反向查询,这就是表关联对象的访问

    #如果模型I有一个ForeignKey,那么该ForeignKey 所指的模型II实例可以通过一个管理器回前面有ForeignKey的模型I的所有实例。默认情况下,
    #这个管理器的名字为foo_set,其中foo 是源模型的小写名称。
    >>> d1.student_set.all() #用这一步就可以查出d1学院下所有的学生数 #为了简便起见,可以在定义时设置related_name 参数来覆盖foo_set 的名称 department = models.ForeignKey('Department', related_name='student', #这一步将foo_set覆盖为student on_delete=models.CASCADE)

      同理,manytomany也可以用related_name来覆盖

      处理关联对象的一些方法add,create

    #add(obj1, obj2, ...)  添加的已经存在数据库的数据,添加一指定的模型对象到关联的对象集中。

    #create(**kwargs)  添加不存在的数据 ,将数据直接存入数据库,创建一个新的对象,将它保存并放在关联的对象集返回新创建的对象。

    from django.shortcuts import render
    from django.http import HttpResponse
    
    # Create your views here.
    
    from .models import Department,Student,Stu_Detail,Course
    
    def test1(request):
        d1 = Department.objects.get(d_id=1)
        s1 = Student.objects.get(s_id=1)
        c1 = Course.objects.get(c_id=1)
        print(d1.student.all()) #d1学院下的所有学生,这是一对多关系;管理器,可通过all()实现
        print(s1.department)    #s1所属学院,这是模型类里面的属性,可以直接访问
        print(c1.student.all()) #报c1课程的所有学生,这是多对多关系,模型有些这个属性;管理器,可通过all()实现
        print(s1.course.all())  #s1学生所报的课程,这也是多对多关系,可以通过反向查询_set来实现,可以用related_name来修改反向查询;
                                # 管理器,可通过all()实现
    
        ##add()  必须是在数据库存在的对象,才能添加;
        #方法一: 可以修改内容,例如本来是计算机学院的,将他改为软件学院
        print(d1.student.all())
        s4 = Student.objects.get(s_id=4)
        d1.student.add(s4) #原本存在s4属于d2学院,通过add将其改为d1学院
        #方法二:添加
        # s8 = Student(s_name='小狗子')
        # s8.save()
        s8 = Student.objects.get(s_id=8)
        d1.student.add(s8) #将原本department为空的s8添加到d1学院中去
    
        ##create()  添加数据到数据库
        s1.course.create(c_name='英语') #通过学生s1的课程中添加一个新的课程英语,同时在student表和course表里面都添加了数据
        d1.student.create(s_name='小熊')
    
        ##remove() 删除
        d1.student.remove(s1) #将学生s1从d1学院里面删除
        s1.course.remove(c1) #将课程c1从学生s1的课程表中删除
    
        ##clear() 清空
        s1.course.clear() #清空学生s1的所有课程
    
        return HttpResponse('这是表关联对象的方法')

    二、多表查询

    #Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,它在后台自动帮你处理JOIN。 若要跨越关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔,直至你想要的字段
        ##多表查询
        rs = Student.objects.filter(department__d_name='计算机学院')      #查询学院名称为'计算机学院'的学生的信息
        rs = Department.objects.filter(student__s_name__contains='')  #查询学生名字中包含小的学院的信息
        rs = Course.objects.filter(student__s_id=1)                     #查询学号为1的课程的信息
        rs = Student.objects.filter(course__c_id=1)                     #查询报名课程1的学生的信息
        rs = Department.objects.filter(student__course__c_name='python') #查询报了python课程的学生的所属学院的信息

     三、其他查询

      聚合查询:aggregate()是queryset的一个终止子句,它返回一个包含一些键值对的字典

    from django.db.models import Count,Avg,Max,Min,Sum
    def test(request):
        rs = User.objects.all().aggregate(Avg('age')) #求User表中age的平均数,返回的是字典
        rs = User.objects.all().aggregate(average_age=Avg('age')) #重命名为average_age
        rs = User.objects.all().aggregate(Max('age'),Min('age'),Sum('age')) #求User表中age的最大值,最小值,和,返回的是字典
        print(rs)
        return HttpResponse('XXXX')

      分组查询:为调用的queryset中每一个对象都生成一个独立的统计值

        #分组查询
        rs = Student.objects.all().values('department').annotate(count=Count('department')).values('department_id','count')
            #查询每个学院有多少个学生,以department为第一查询,多少个学生也就是count为第二查询,最后以department_id和count的形式输出
        rs = Student.objects.all().values('course').annotate(count=Count('course')).values('s_name','count')
            #每个学生报名的课程数量
        rs = Course.objects.all().values('student').annotate(count=Count('student')).values('c_name','count')
            #每个课程报名的学生数

      F查询:针对两个字段的值的比较

        #F查询
        rs = Student.objects.filter(department__d_id__gt=F('s_id')) #学院id小于学生学号的
        rs = User.objects.all().update(age=F('age')+1) #给User表中所有的age加一

      Q查询:多条件查询

        #Q查询
        rs = User.objects.filter(name='taka',age='19') #这是且条件,必须是name为taka,age为19的
        rs = User.objects.filter(Q(name='taka')|Q(name='budong')) #这是或条件
        rs = User.objects.filter(Q(name='tuple')&~Q(age=100)) #这是名字为tuple,id不等于3的条件

  • 相关阅读:
    温故而知新-错误和异常处理
    温故而知新-面向对象的PHP
    Django框架之模板语法【转载】
    django2.0实现数据详情页展示的流程
    django2.0表的ORM字段类型和展示
    Fatal error: Cannot use object of type PHPExcel_RichText as array
    django2.0数据展示流程
    django2.0模板相关设置
    django2.0新增功能流程
    django2.0设置默认访问路由
  • 原文地址:https://www.cnblogs.com/xuchengcheng1215/p/9387831.html
Copyright © 2011-2022 走看看