• Django入门--模型系统(二):常用查询及表关系的实现


    1.常用查询

    模型类上的管理器: ** 模型类.objects **

    (1)常用一般查询
    rs = Student.objects.all()                       # 查询所有记录,返回Queryset
    print(rs.query)                                  # 返回rs的SQL语句, 针对Queryset对象
    rs = Student.objects.filter(name='XM')           # 条件查询, 可传多个参数, 返回Queryset
    # from django.db.models import Q
    # Student.objects.filter(Q(age=20)|Q(age=18))    #多条件OR查询
    rs = Student.objects.exclude(name='XM')          # 查询排除name='XM'的记录, 可传多个参数, 返回Queryset
    rs = Student.objects.get(id=2)                   # 查询一条记录, 返回对象, 若果有多个对象符合, 则会报错
    rs = Student.objects.first()                     # 查询第一条数据, 返回对象,不能query
    rs = Student.objects.last()                      # 查询最后一条数据, 返回对象
    
    rs = Student.objects.order_by('age')                # 对年龄结果排序
    rs = Student.objects.order_by('age', 'id')          # 多项排序
    rs = Student.objects.order_by('-age')               # 反向排序
    # from django.db.models.functions import Lower
    # rs = Sudent.objects.order_by(Lower('name').desc)   # 名字转成小写,并从大到小排序
    
    rs = Student.objects.values('name').filter(age=20)# 针对name字段查询, 返回字典列表
    rs = Student.objects.all().values()               # 将返回的QuerySet中的Model转换成字典
    rs = Student.objects.only('name')                 # 与values一样, 区别是除了name字段还返回id字段, 返回对象
    rs = Student.objects.only('name').filter(age=0) 
    rs = Student.objects.defer('name')              # 查询除name以外的字段, 用法与only相同, 作用相反, 返回对象
    
    rs = Student.objects.all()[:5]                      # 切片, 相当于limit,不支持负索引, 返回Queryset
    rs = Student.objects.all()[::2]                     # 支持步长,返回列表对象  
         ## 切片后, 不再支持附加条件过滤和索引   
    
    (2)常用条件查询

    支持exclude、filter、get,返回Queryset

    rs = Student.objects.filter(name__exact='XM')       # exact等于, 相当于"=", iexact为忽略大小写
    rs = Student.objects.filter(name__contains='X')     # contains包含相当于"like", icontains为忽略大小写
    rs = Student.objects.filter(name__startswith='X')   # startswith以什么开头, istartswith为忽略大小写
    rs = Student.objects.filter(name__endswith='M')     # endswith以什么结尾, iendswith为忽略大小写
    
    rs = Student.objects.filter(age__in=[18, 19, 20])   # in成员所属
    rs = Student.objects.filter(age__gt=20)             # gt大于、gte大于等于、lt小于、lte小于等于
    rs = Student.objects.filter(age__range=(18,25))     # range区间
    rs = Student.objects.filter(city__isnull=True)      # isnull判断是否为空   
    
    (3)聚合查询

    导入模块: from django.db.models import Count, Avg, Max, Min, Sum,通过Queryset的aggregate()调用

    from django.db.models import Count, Avg, Max, Min, Sum
    rs = Student.objects.count()                       # 获取当前查询到的数据的总数, 返回Int, 支持附加条件过滤
    rs = Student.objects.filter(name__startswith='X').count()       
    rs = Student.objects.aggregate(age_avg=Avg('age')) # 获取年龄平均值, age_avg为命名, 返回字典, 支持附加条件过滤
    rs = Student.objects.aggregate(age_max=Max('age'))
    rs = Student.objects.aggregate(age_min=Min('age'))
    rs = Student.objects.aggregate(age_sun=Sum('age'))
    
    (4)分组查询

    与values、Count等聚合查询语句一起使用,需要导入聚合查询模块, 通过Queryset的annotate()调用

    # 分性别查询男女生人数
    '''SQL语句:select sex, count(sex) as num from student group by sex;'''
    from django.db.models import Count, Avg, Max, Min, Sum
    rs = Student.objects.values('sex').annotate(num=Count('sex'))# values为分组的字段,num为命名,返回字典列表
    rs = Student.objects.values('sex').annotate(num = Avg('sex'))      
    

    2.常用的模型字段类型

    IntegerField       整型,映射到数据库中的int型
    AutoField         整型,具有自增长属性,添加"primaty_key=True"就是一个主键
    CharField         字符型,映射到数据库中的varchar类型,必须通过max_length指定长度
    TextField         文本类型,映射到数据库中的text类型
    BooleanField      布尔类型,映射 到数据库中的 tinyint类型,传递True/False,如果可以为空时,使用NullBooleanField
    DateField         日期类型,映射到数据库中的date类型,
    设置DateField.auto_now=True可以设置该字段为当前时间, 每次修改模型内容该字段都会变化
    设置DateField.auto_now_add=True可以设置当对象第一次创建时自动设置当前时间, 时间固定,不会随着模型变化而变化

    DateTimeField       日期时间类型,映射到数据库中的datetime类型,在使用的时候传递datetime.detetime()进去

    3.Field常用参数

    primary_key               指定是否为主键
    unique                指定是否唯一
    null                   指定是否为空,默认为False
    blank                    等于True时form表单验证时可以为空,默认为False
    default                 设置默认值
    DateField.auto_now           每次修改都会将当前的时间更新
    DateField.auto_add_now      第一次添加进去,都会将当前时间设置进去,以后修改,不会改变该值

    4.表关系的实现

    (1)OneToOne

    用一张表的主键外键关联另一张表的主键

     # 设置on_delete,当删除某个学生,该生的详情信息也会删掉
    student = models.OneToOneField('student', on_delete=models.CASCADE)  
    

    example:学生表与学生详情表建立一对一的关系

    from django.db import models
    
    class Student(models.Model):
        name = models.CharField(max_length=20)     # 字符串,max_length必须给
        age = models.SmallIntegerField(default=0) # default默认值
        sex = models.SmallIntegerField(default=1)
        qq = models.CharField(max_length=20, unique=True, null=True)
        phone = models.CharField(max_length=30, unique=True, null=True)
        c_time = models.DateTimeField(verbose_name='报名时间', auto_now_add=True)
        e_time = models.DateTimeField(verbose_name='编辑时间', auto_now=True)
    
        def __str__(self):
            return '%s-%s' %(self.name, self.age)
    
    class StudentDetail(models.Model):
        num = models.CharField(max_length=20, default='')
        college = models.CharField(max_length=20, default='')
        student = models.OneToOneField('student', on_delete=models.CASCADE)
    
    (2)OneToMany

    一对多,在属于多的模型创建一个外键字段,关联另一张表

    #设置on_delete,当删除某个年级,该年级的学生的grade字段显示'null'
    grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)       
    

    example:班级表与学生表建立一对多的关系

    from django.db import models
    
    class Student(models.Model):
        name = models.CharField(max_length=20)
        age = models.SmallIntegerField(default=0) 
        sex = models.SmallIntegerField(default=1)
        qq = models.CharField(max_length=20, unique=True, null=True)
        phone = models.CharField(max_length=30, unique=True, null=True)
        grade = models.ForeignKey('Grade', on_delete=models.SET_NULL, null=True)
        c_time = models.DateTimeField(verbose_name='报名时间', auto_now_add=True)
        e_time = models.DateTimeField(verbose_name='编辑时间', auto_now=True)
    
        def __str__(self):
            return '%s-%s' %(self.name, self.age)
    
    class Grade(models.Model):
        name = models.CharField(max_length=20, default='')
        num = models.CharField(max_length=20, default='')
    
        def __str__(self):
            return '%s-%s' %(self.num, self.name)
    
    (3)ManyToMany

    example:建立学生表与课程表的多对多关系

    from django.db import models
    
    class Student(models.Model):
        name = models.CharField(max_length=20) 
        age = models.SmallIntegerField(default=0) 
        sex = models.SmallIntegerField(default=1)
        qq = models.CharField(max_length=20, unique=True, null=True)
        phone = models.CharField(max_length=30, unique=True, null=True)
        c_time = models.DateTimeField(verbose_name='报名时间', auto_now_add=True)
        e_time = models.DateTimeField(verbose_name='编辑时间', auto_now=True)
    
        def __str__(self):
            return '%s-%s' %(self.name, self.age)
    
     # 多对多
    class Course(models.Model):
        name = models.CharField('课程名称', max_length=20, default='')
        students = models.ManyToManyField('Student', through='Enroll')
    # 没有"through='Enroll'",系统则自动创建第三张表"Course_Student",该表只有‘student’和‘course’两个字段;
    # 如果要添加其他字段,则要手动创建第三张表"Enroll",并设置"through='Enroll'"参数
    
        def __str__(self):
            return self.name
    
    class Enroll(models.Model):
        student=models.ForeignKey('Student', on_delete=models.CASCADE)
        course=models.ForeignKey('Course', on_delete=models.CASCADE)
        pay=models.FloatField('缴费金额', default='')
        c_time=models.DateTimeField('报名时间', auto_now_add=True)
    
  • 相关阅读:
    jquerymobile 页面间URL传值
    xcode 静态链接库的问题
    iPad 用户体验关键要素
    Enable SharePoint Designer for Project Web App PWA 2010
    后台定位
    做一个iPhone应用需要花多少钱?
    ios无法获取坐标
    重装系统后ORACLE数据库恢复的方法
    【Web】百度有聊官网的一些布局不好之处
    【Pagoda】在pagodabox里建立项目并连接数据库
  • 原文地址:https://www.cnblogs.com/rongzhen/p/10495143.html
Copyright © 2020-2023  润新知