django 的 ORM

数据库配置和迁移

  • Django项目默认 sqlite3 数据库, 生成的数据库名为 db.sqlite3
  • sqlite3 仅供测试使用,可以通过配置修改为使用 mysql

一、配置使用MySQL数据库

  1. 手动创建 MySQL 数据库,比如叫: db_django01

     create database db_django01 charset=utf8;
    
  2. 在与项目 setting.py 文件中配置使用mysql

     DATABASES = {
         'default': {
             # 配置使用mysql
             'ENGINE': 'django.db.backends.mysql',     # 数据库产品
             'HOST': "localhost",           # 数据库ip
             'PORT': 3306,                  # 数据库端口
             'USER': "root",                # 用户名
             'PASSWORD': "mysql",           # 密码
             'NAME': "db_django01",         # 数据库名
         }
     }
    
  3. 在python虚拟环境下安装 MySQL 驱动

       pip install pymysql
    
  4. 在 与项目同名的包 下的 __init__.py 文件中,初始化MySQL驱动

     import pymysql
     pymysql.install_as_MySQLdb()
    

二、迁移命令生成表

打开终端,进入到项目根目录下,执行以下2个命令,生成数据库表

1. 生成迁移文件

python manage.py makemigrations

2. 生成数据库表

python manage.py migrate

3. 查看数据库表

image

一、需求

定义模型类,保存部门-员工数据

  • 部门类(Department)

    • 部门名称: name
    • 部门成立时间: create_date
    • 逻辑删除标识:is_delete
  • 员工类(Employee)

    • 姓名: name
    • 年龄: age
    • 性别: sex
    • 工资: salary
    • 入职时间: hire_date
    • 备注信息: comment

二、模型类定义

  • 模型类被定义在 应用/models.py 文件中
  • 模型类必须继承自 Django 的 models.Model 类

1. 属性定义

  • 格式

      属性名 = models.字段类型(字段选项)
    
  • 属性名不能是python的保留关键字
  • 属性名不能使用连续的下划线(这是由django的查询方式决定的)

2. 关于主键

  • 主键:primary key,简写 pk
  • 不需要主动定义,django会自动生成自增长的主键,属性名叫 id,
  • 如果开发者自己定义了主键,则django不会再生成默认的主键

3. 表名

  • 默认为:应用名小写_模型类名小写
  • 可通过通过Meta类指定表名,例如

      # 如果应用名为users,则默认表名为:users_department
      class Department(models.Model):
          ...
          class Meta:
              # 指定生成的数据库表的名字
              db_table = 'department'
    

4. 字段类型

类型说明
AutoField自动增长的IntegerField,通常不用指定,不指定时Django会自动创建名为id的自动增长属性
BooleanField布尔字段,值为True或False
NullBooleanField支持Null、True、False三种值
CharField字符串,必须指定:max_length,表示最大字符个数
TextField大文本字段,一般超过4000个字符时使用
IntegerField整数
DecimalField十进制浮点数,用python中的Decimal实例来表示
必须指定: max_digits最大位数,decimal_places小数位数。 
FloatField浮点数
DateField日期 
1) 参数auto_now表示每次修改保存对象时,自动设置该字段为当前时间,用于保存"最后一次修改"时间,默认为False; 
2) 参数auto_now_add表示当对象第一次被创建时自动设置保存当前时间,用于保存"创建时间"时间,默认为值为False; 
3) 参数auto_now_addauto_now是相互排斥的,不能同时用到一个属性中
TimeField时间,参数同DateField
DateTimeField日期时间,参数同DateField
FileField上传文件字段
ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片

4. 字段选项

选项默认值描述是否要迁移修改表结构
nullFalseTrue表示表字段允许为空
uniqueFalseTrue表示表字段不能重复
db_column属性名称表字段名称
primary_keyFalseTrue表示字段设置为了主键,一般作为AutoField的选项使用
db_indexFalse创建索引
default-默认值
blankFalse在django管理后台新增或编辑一条表数据时,该字段是否允许为空;
null是数据库范畴的概念,blank是表单验证范畴的
choices-在django管理后台新增或编辑一条表数据时,该字段显示为下拉框,默认为编辑框
  • choices: 性别属性使用了choices选项后,在录入一条数据时,会以下拉框显示
  • blank:blank属性默认值为false, 表示录入一条数据时,当前字段必须填写,不能为空,否则js端js校验不通过,例如:下图的comment员工备注信息字段。

    image

5. 外键(关联属性)

在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

关联属性on_delete选项的取值

  • models.CASCADE 此为默认值,级联删除,会删除关联数据

    department = models.ForeignKey('Department', on_delete=models.CASCADE)
    
  • models.PROTECT 只要存在关联数据就不能删除

    department = models.ForeignKey('Department', on_delete=models.PROTECT)
    
  • models.SET_NULL 删除数据后关联字段设置为NULL,仅在该字段允许为null时可用(null=True

 

二、代码参考

部门和员工模型类 代码参考

class Department(models.Model):
    """部门类"""

    # 部门名称:字符串类型(必须要指定最大长度)
    name = models.CharField(max_length=20)
    # 部门成立时间: 日期类型
    create_date = models.DateField(auto_now_add=True)
    # 逻辑删除标识:标识部门是否删除
    is_delete = models.BooleanField(default=False)

    def __str__(self):
        return self.name

    class Meta: 
        # 指定表名
        db_table = 'department'

class Employee(models.Model):
    """员工类"""

    choices_gender = (
        (0, '男'),
        (1, '女'),
    )

    name = models.CharField(max_length=20)
    age = models.IntegerField()
    gender = models.IntegerField(default=0, choices=choices_gender)
    # 工资:浮点类型(必须要指定两个选项)  999999.99
    salary = models.DecimalField(max_digits=8, decimal_places=2)
    # 备注信息: 可以为空
    comment = models.CharField(max_length=300, null=True, blank=True)
    # 员工入职时间
    hire_date = models.DateField(auto_now_add=True)
    # 一对多的外键:员工所属部门 department_id
    department = models.ForeignKey('Department')

    def __str__(self):
        return self.name

    class Meta: 
        # 指定表名
        db_table = 'employee'

模型管理器

模型管理器:objects属性

  1. 每个模型类默认都有一个叫 objects 的类属性,它由django自动生成
  2. 我们把 objects 称为 模型管理器,其类型为: django.db.models.manager.Manager
  3. 通过objects属性,可以实现对数据库相关的操作,常用方法如下
objects管理器中的方法返回类型作用
模型类.objects.create()模型类对象创建一个对象(新增一条数据)
模型类.objects.get()模型对象查询一个对象,且只能有一个
如果查到多条数据,则报:MultipleObjectsReturned 
如果查询不到数据,则报:DoesNotExist
模型类.objects.all()QuerySet查询所有的对象
模型类.objects.count()数字查询总共有多少条数据
模型类.objects.filter()QuerySet查询满足条件的对象
模型类.objects.exclude()QuerySet查询不满条件的对象
模型类.objects.order_by()QuerySet对查询结果集进行排序
模型类.objects.aggregate()字典,例如:
{'salary__avg': 9500.0}
进行聚合操作
Sum, Count, Max, Min, Avg

 

数据增删改

1、增

  1. 模型类对象.save()

     # 新增部门
     d = Department()
     d.name = '人事部'
     d.create_date = '2017-1-1'
     d.save()
    
     # 新增员工
     e = Employee()
     e.name = '龙五'
     e.age = 30
     e.gender = 0
     e.salary = 10000
     # 注意关联属性的赋值
     e.department = Department.objects.get(id=1)
     e.save()
    
  2. 模型类.objects.create(属性1=值1,属性2=值2, ...)

     Department.objects.create(
             name='后勤部',
             create_date='2017-1-1'
         )
    

2、删

  1. 模型类对象.delete()

     d = Department.objects.get(id=1)
     d.delete()
    
  2. 模型类.filter(条件).delete()

    Department.objects.filter(id=1).delete()

    关联属性on_delete选项的取值

    • models.CASCADE 此为默认值,级联删除,会删除关联数据

        department = models.ForeignKey('Department', on_delete=models.CASCADE)
      
    • models.PROTECT 只要存在关联数据就不能删除

        department = models.ForeignKey('Department', on_delete=models.PROTECT)
      
    • models.SET_NULL 删除数据后关联字段设置为NULL,仅在该字段允许为null时可用(null=True

3、改

  1. 模型类对象.save()

     # 方式一: 调用save方法
     d = Department.objects.get(id=1)
     d.name = '人事部'
     d.save()
    

    注意:id 已存在,调用 save 方法时为修改,否则为新增

  2. 模型类.filter(条件).update(属性1=值1,属性2=值2, ...)

 Department.objects.filter(id=1).update(name='人事部')

查询

本节内容

  1. 条件查询
  2. F对象
  3. Q对象
  4. 聚合
  5. 排序
  6. 关联查询

一、条件查询

  1. 调用 filter方法: 模型类.objects.filter(模型类属性名__条件名=值)
  2. 返回包含查询结果数据的 QuerySet 对象

练习案例:

  1. 判等: exact

    例:查询id为1的员工

     select * from employee where id=1;
     Employee.objects.filter(id__exact=1)
     Employee.objects.filter(id=1)
    
  2. 模糊查询: contains / endswith / startswith

    例:查询名字包含'马'的员工

     select * from employee where name like '%马%';
     Employee.objects.filter(name__contains='马')
    
     # 例:查询名字以'军'结尾的员工
     select * from employee where name like '%军';
     Employee.objects.filter(name__endswith='军')
    
  3. 空查询: isnull

    例:查询备注信息不为空的员工

     select * from employee where comment is not null ;
     Employee.objects.filter(comment__isnull=False)
    
  4. 范围查询: in

    例:查询id编号为1或3或5的员工

     select * from employee where id in (1, 3, 5); 
     Employee.objects.filter(id__in=[1,3,5])
    
  5. 比较查询: gt(greater than)、lt(less than)、gte、lte

    例:查询age大于等于30的员工

     select * from employee where age >= 30; 
     Employee.objects.filter(age__gte=30)
    
  6. 日期查询: year、month、day、week_day、hour、minute、second

    例:查询2015年入职的员工

     select * from employee where year(hire_date) = 2015; 
     Employee.objects.filter(hire_date__year=2015)
    
     # 例:查询2014年1月1日后入职的员工
     select * from employee where hire_date >= '2014-1-1';
     Employee.objects.filter(hire_date__gte='2014-1-1')
    

二、exclude方法

  • 返回不满足条件的数据,用法: 模型类.objects.exclude(条件)

    例:查询id不为3的员工

     select * from employee where id != 3; 
     Employee.objects.exclude(id=3)
    

 

三、F对象

之前的查询都是对象属性与常量值比较,如果要比较两个属性怎么做呢? 比如:查询语文分数大于数学分数的学生

姓名数学语文英语
Tom959095
Jack959095
Rose909298
  1. F对象:比较表中的两个字段,接收的参数为一个字符串
  2. 用法: F('属性名')

    • 比如:成绩表.objects.filter(语文__gt=F('数学'))
    • 需要导包: from django.db.models import F
  3. 案例

    例:查询年龄大于id的员工信息(无实际意义)

     select * from employee where age > id; 
     Employee.objects.filter(age__gt=F('id'))
    
     # 例:查询年龄大于4倍id编号的员工信息
     select * from employee where age > id * 4; 
     Employee.objects.filter(age__gt=F('id') * 4 )
    

 

四、Q对象

  • 作用: 对查询条件进行 与 或 非 (& | ~) 的逻辑操作
  • 用法: 先导入 from django.db.models import Q

    • 与: Q(查询条件1) & Q(查询条件2)
    • 或: Q(查询条件1) | Q(查询条件2)
    • 非: ~Q(查询条件)
  • 案例

    例:查询id大于3且年龄大于30的员工信息。

     select * from employee where id > 3 and age > 30; 
     Employee.objects.filter(id__gt=3, age__gt=30)
     Employee.objects.filter(Q(id__gt=3) & Q(age__gt=30))
    
     # 例:查询id大于3或者年龄大于30的员工信息。
     select * from employee where id > 3 or age > 30; 
     Employee.objects.filter(Q(id__gt=3) | Q(age__gt=30))
    
     # 例:查询id不等于3员工信息。
     select * from employee where id != 3; 
     Employee.objects.filter(~Q(id=3))
    

 

五、排序

  • 作用: 对查询结果进行排序,默认为升序
  • 用法:

    升序: 模型类.objects.order_by('属性名')
    降序: 模型类.objects.order_by('-属性名')

  • 示例:

    例:查询所有员工信息,按照id从小到大进行排序。

     select * from employee order by id asc; 
     Employee.objects.order_by('id')
    
     # 例:查询所有员工信息,按照id从大到小进行排序。
     select * from employee order by id desc; 
     Employee.objects.order_by('-id')
    
     # 例:把id大于8的员工信息, 按年龄从大到小排序显示;
     select * from employee where id > 8 order by age desc; 
     Employee.objects.filter(id__gt=8).order_by('-age')
    

 

六、aggregate 方法

  • 作用: 聚合操作,对多行查询结果中的一列进行操作,返回一个值
  • 用法: 模型类.objects.aggregate(聚合类('属性名'))

    • 常用聚合类有:Sum, Count, Max, Min, Avg等
    • 返回值是一个字典, 格式: {'属性名__聚合函数': 值}
    • 使用时需要先导入聚合类: from django.db.models import Sum, Count, Max, Min, Avg
  • 案例:

    例:查询所有员工的平均工资

     select avg(salary) from employee; 
     Employee.objects.aggregate(Avg('salary'))
    

 

七、关联查询

一、通过 对象 进行关联查询

  1. 有关联属性(多对一查询): 模型类对象.关联属性
  2. 没有关联属性(一对多查询):模型类对象.关联模型类类名小写_set.all()

1540523551571

 # 查询 “研发部” 的所有员工
 d = Department.objects.get(name='研发部')
 d.employee_set.all()    

 # 例:查询 “赵小二” 所属的部门信息
 e = Employee.objects.get(name='赵小二')
 e.department

二、通过模型类查询

  • 模型类.objects.filter(关联属性__属性名__操作符=值)
  • 模型类.objects.filter(关联模型类类名小写__属性名__操作符=值)

实现参考:

# 查询 “研发部” 的所有员工
Employee.objects.filter(department__name__exact='研发部')
# 例:查询 “赵小二” 所属的部门信息
Department.objects.filter(employee__name__exact='赵小二')
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值