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

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
  • 获取第一条
In [3]: Students.objects.first() 
Out[3]:     #返回的是对象
  • 获取最后一条
In [4]: Students.objects.last()
Out[4]: 
  • get(**kwargs)根据给定的条件获取一个对象,如果符合多个,或者没有就会报错
In [5]: Students.objects.get(pk=1)
Out[5]: 
  • filter(**kwargs)过滤,根据参数提供的条件,获取一个过滤器后的QuerySet,多个条件等于 select 语句使用and连接
In [17]: Students.objects.filter(name='小明').first()                                      
Out[17]: 
  • exclude()排除,作用和filter()相反
In [19]: Students.objects.exclude(pk=1)                                              
Out[19]: , ]>
  • 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]: , , ]>
In [21]: Students.objects.all().order_by('name','-age')      #根据age反序排序             
Out[21]: , , ]>
  • 切片:使用列表的切片语法操作QuerySet,除了不能负索引,其他的都可以,他等价于select语句里面的LIMITOFFSET字句
In [24]: Students.objects.all().order_by('name')[::-1]                                         
Out[24]: [, , ]

限制字段查询

  • values(*fields)返回QuerySet,这个QuerySet返回的是一个字典列表。参数fields指定了select中我们想要限制查询的字段。返回的字典列表 中,只会包含我们指定的字段,如果不指定,包含所有字段。
In [25]: Students.objects.values('name')                                                       
Out[25]: 

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]: , , ]>
  • 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]: , ]>

查询条件

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

In [30]: Students.objects.filter(name__exact='小米')    # 等同于namet='小米'     
Out[30]: ]>
  • 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]: 

关于聚合查询的详细介绍 ==》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模型系统 ② 常用查询及表关系的实现)