美文网首页
Django框架(七):Django模型系统 ② 常用查询及表关

Django框架(七):Django模型系统 ② 常用查询及表关

作者: 加州旅馆_6741 | 来源:发表于2019-04-05 22:22 被阅读0次

    1.常用查询

    每一个Django模型类,都有一个默认的管理器objects
    QuerySet表示数据库中对象的列表,他可以有0到多个过滤器,过滤器通过给定的参数缩小查询范围。
    QuerySet等同于select语句,过滤器是一个限制字句,比如where,比如limit。

    • all() 获取所有
    In [1]: from teacher.models import Students   
    In [2]: Students.objects.all()
    Out[2]: <QuerySet [<Students: 小米>, <Students: 小明>, <Students: 小李>]>  ##返回的是QuerySet
    
    • 获取第一条
    In [3]: Students.objects.first() 
    Out[3]: <Students: 小米>    #返回的是对象
    
    • 获取最后一条
    In [4]: Students.objects.last()
    Out[4]: <Students: 小李>
    
    • get(**kwargs)根据给定的条件获取一个对象,如果符合多个,或者没有就会报错
    In [5]: Students.objects.get(pk=1)
    Out[5]: <Students: 小米>
    
    • filter(**kwargs)过滤,根据参数提供的条件,获取一个过滤器后的QuerySet,多个条件等于 select 语句使用and连接
    In [17]: Students.objects.filter(name='小明').first()                                      
    Out[17]: <Students: 小明>
    
    • exclude()排除,作用和filter()相反
    In [19]: Students.objects.exclude(pk=1)                                              
    Out[19]: <QuerySet [<Students: 小明>, <Students: 小李>]>
    
    • get_or_create() 有则获取,无则创建,返回一个由(object, created)组成的元组,元组中的object 是一个查询到的或者是被创建的对象, created 是一个表示是否创建了新的对象的布尔值。
      get_or_create() 函数的详细介绍 https://www.cnblogs.com/zhongbokun/p/9732698.html

    排序

    • order_by(*fields),根据给定的字段排序
    In [20]: Students.objects.all().order_by('name')     #根据name字段正序排序                                     
    Out[20]: <QuerySet [<Students: 小明>, <Students: 小李>, <Students: 小米>]>
    In [21]: Students.objects.all().order_by('name','-age')      #根据age反序排序             
    Out[21]: <QuerySet [<Students: 小明>, <Students: 小李>, <Students: 小米>]>
    
    • 切片:使用列表的切片语法操作QuerySet,除了不能负索引,其他的都可以,他等价于select语句里面的LIMITOFFSET字句
    In [24]: Students.objects.all().order_by('name')[::-1]                                         
    Out[24]: [<Students: 小米>, <Students: 小李>, <Students: 小明>]
    

    限制字段查询

    • values(*fields)返回QuerySet,这个QuerySet返回的是一个字典列表。参数fields指定了select中我们想要限制查询的字段。返回的字典列表 中,只会包含我们指定的字段,如果不指定,包含所有字段。
    In [25]: Students.objects.values('name')                                                       
    Out[25]: <QuerySet [{'name': '小米'}, {'name': '小明'}, {'name': '小李'}]>
    
    In [26]: print(Students.objects.values('name').query)                                                              
    SELECT `teacher_students`.`name` FROM `teacher_students`
    
    • only(*fields)返回一个 QuerySet,跟values一样,不同的是这个QuerySet是对象列表,only一定包含主键。
    In [27]: Students.objects.only('name')                                                           
    Out[27]: <QuerySet [<Students: 小米>, <Students: 小明>, <Students: 小李>]>
    
    • defer(*fields)用法与only相反

    多条件OR连接

    需要使用or条件,我吗要使用到Q对象

    In [28]: from django.db.models import Q    #导入Q模块
    
    In [29]: Students.objects.filter(Q(name='小米')|Q(name='小明'))                  
    Out[29]: <QuerySet [<Students: 小米>, <Students: 小明>]>
    

    查询条件

    相当于是SQL语句中的where语句后面的条件,语法为字段名__规则

    In [30]: Students.objects.filter(name__exact='小米')    # 等同于namet='小米'     
    Out[30]: <QuerySet [<Students: 小米>]>
    
    • exact - 精确匹配
    • iexact - 忽略大小写
    • contains - 模糊匹配,等同于%条件%
    • icontains - 大小写不敏感模糊匹配
    • in - 字段名__规则=列表 只要条件在列表中都匹配
    • gt - 大于
    • gte - 大于等于
    • lt - 小于
    • lte - 小于等于
    • startwith - 以什么条件开始
    • istartwith - 以什么条件开始,忽略大小写
    • endwith - 以什么结尾
    • iendwith - 以什么结尾,忽略大小写
    • range - 范围区间
    • isnull - filter(age__isnull=True)字段为空的

    聚合函数

    • count统计数量 (严格来说不算聚合函数)
    In [31]: Students.objects.all().count()                                                     
    Out[31]: 3
    
    • Avg 计算平均值
    In [32]: from django.db.models import Avg #导入模块
    In [34]: Students.objects.aggregate(age_avg=Avg('age'))                                                                 
    Out[34]: {'age_avg': 15.0}
    
    • Max - 找出最大值
    • Mix - 找出最小值
    • Sum - 计算求和
    分组聚合

    分组需要结合values,annotate和聚合 ,方法 看下面的案例
    查询男生女生多少人:

    In [35]: from django.db.models import Count  
    
    In [37]: Students.objects.values('sex').annotate(Count('sex'))        
    Out[37]: <QuerySet [{'sex': 1, 'sex__count': 3}]>
    

    关于聚合查询的详细介绍 ==》https://blog.csdn.net/weixin_42134789/article/details/84567365

    2.常用模型字段类型

    • int - IntegetField:整型,映射到数据库中的int类型
    • varchar - CharField : 字符类型,映射到数据库中的varchar类型,通过max_length指定最大长度,max-length为必须参数,否则会报错
    • longtext - TextField:文本类型,映射到数据库中的text类型
    • tinyint - 布尔类型,映射到数据库中的tinyint类型,在使用的时候,传递True/False进去。如果要可以为空,则用NullBooleanField
    • date - DateField:日期类型,没有时间
    • datetime - DateTimeField:日期时间类型。映射到数据库中的是datetime类型,在使用的时候,可以设置DateField.auto_now每次保存对象时,自动设置该字段为当前时间。设置DateField.auto_now_add当对象第一次被创建时自动设置当前时间

    3.常用模型字段参数

    • primary_key: 指定是否为主键
    • unique: 指定是否唯一。
    • null: 指定是否为空,默认为False。
    • blank: 等于True时form表单验证时可以为空,默认为False。
    • default: 设置默认值。
    • DateField.auto_now: 每次修改都会将当前时间更新进去,只有调用,QuerySet.update方法将不会调用。这个参数只是Date和DateTime以及TimModel.save()方法才会调用e类才有的。
    • DateField.auto_now_add: 第一次添加进去,都会将当前时间设置进去。以后修改,不会修改这个值

    4.表关系实现

    Django中,模型通过特殊的字段进行关系连接

    • 一对一

    from django.db import models
    
    # Create your models here.
    
    class Students (models.Model): # 一个类代表一个数据表
        id = models.AutoField(primary_key=True) ##创建一个可以自动生成的主键,这条也可以不写,Django中会自动生成主键
        name = models.CharField(verbose_name='姓名',max_length=20)   ##创建字符类型字段,最大长度为20,设置提示信息'姓名'
                                                ### max_length为CharField的必须参数
        age = models.SmallIntegerField(verbose_name='年龄',null=True) ##创建值可以为null的小整型字段,
        sex = models.SmallIntegerField(default=1)   ##创建缺省值为1的小整型字段
        qq = models.CharField(max_length=20,null=True)
        phone = models.CharField(max_length=20,null=True)
        c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)  ##创建日期时间类型字段,自动创建当前时间
    
        def __str__(self):
            return self.name
    
    class StudentsDetail(models.Model):  #学生详情表
        student = models.OneToOneField('Students',on_delete=models.CASCADE) #一对一关联,关联Students类,on_delete代表级联,关联的Students表删除后自动删除此表
        card_num = models.CharField(verbose_name='身份证号码',max_length=20,unique=True,null=True)
        college = models.CharField('毕业院校',max_length=20,default='家里蹲')
    
    • 一对多

    from django.db import models
    
    # Create your models here.
    
    class Students (models.Model): # 一个类代表一个数据表
        id = models.AutoField(primary_key=True) ##创建一个可以自动生成的主键,这条也可以不写,Django中会自动生成主键
        name = models.CharField(verbose_name='姓名',max_length=20)   ##创建字符类型字段,最大长度为20,设置提示信息'姓名'
                                                ### max_length为CharField的必须参数
        age = models.SmallIntegerField(verbose_name='年龄',null=True) ##创建值可以为null的小整型字段,
        sex = models.SmallIntegerField(default=1)   ##创建缺省值为1的小整型字段
        qq = models.CharField(max_length=20,null=True)
        phone = models.CharField(max_length=20,null=True)
        c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)  ##创建日期时间类型字段,自动创建当前时间
        grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True) #一对多关联,外键关联Grade班级表,models.SET_NULL设置班级表删除后,此字段自动为NULL
    
        def __str__(self):
            return self.name
    
    class StudentsDetail(models.Model):
        student = models.OneToOneField('Students',on_delete=models.CASCADE) #一对一关联,关联Students类,on_delete代表级联,关联的Students表删除后自动删除此表
        card_num = models.CharField(verbose_name='身份证号码',max_length=20,unique=True,null=True)
        college = models.CharField('毕业院校',max_length=20,default='家里蹲')
    
    class Grade(models.Model):
        name = models.CharField('班级名称',max_length=20,)
        num = models.CharField('班期',max_length=20)
    
    • 多对多

    from django.db import models
    
    # Create your models here.
    
    class Students (models.Model): # 一个类代表一个数据表
        id = models.AutoField(primary_key=True) ##创建一个可以自动生成的主键,这条也可以不写,Django中会自动生成主键
        name = models.CharField(verbose_name='姓名',max_length=20)   ##创建字符类型字段,最大长度为20,设置提示信息'姓名'
                                                ### max_length为CharField的必须参数
        age = models.SmallIntegerField(verbose_name='年龄',null=True) ##创建值可以为null的小整型字段,
        sex = models.SmallIntegerField(default=1)   ##创建缺省值为1的小整型字段
        qq = models.CharField(max_length=20,null=True)
        phone = models.CharField(max_length=20,null=True)
        c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True)  ##创建日期时间类型字段,自动创建当前时间
        grade = models.ForeignKey('Grade',on_delete=models.SET_NULL,null=True) #一对多关联,外键关联Grade班级表,models.SET_NULL设置班级表删除后,此字段自动为NULL
    
        def __str__(self):
            return self.name
    
    class StudentsDetail(models.Model):
        student = models.OneToOneField('Students',on_delete=models.CASCADE) #一对一关联,关联Students类,on_delete代表级联,关联的Students表删除后自动删除此表
        card_num = models.CharField(verbose_name='身份证号码',max_length=20,unique=True,null=True)
        college = models.CharField('毕业院校',max_length=20,default='家里蹲')
    
    class Grade(models.Model):
        name = models.CharField('班级名称',max_length=20,)
        num = models.CharField('班期',max_length=20)
    
    class Course(models.Model):
        name = models.CharField('课程名称',max_length=20)
        #student = models.ManyToManyField('Students') #多对多关联,默认会创建一张中间表,当你需要中间表中添加额外字段,最好指定一张中间表
        student = models.ManyToManyField('Students',through='Enroll') #多对多关联,指定Enroll表为中间表
    
    class Enroll(models.Model):  #多对多的中间表,等于一张报名表
        student = models.ForeignKey('Students',on_delete=models.CASCADE) #外键关联学生表
        course = models.ForeignKey('Course',on_delete=models.CASCADE) #外键关联课程表
        c_time = models.DateTimeField(auto_now_add=True)
        paid = models.FloatField('付款',default=0)
    

    相关文章

      网友评论

          本文标题:Django框架(七):Django模型系统 ② 常用查询及表关

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