ORM框架
从数据库中操作数据(增删改查) 1.可以使用pymysql模块执行原生的sql语句去操作数据库 a.sql语句一般比较复杂,并且维护困难 b.sql语句的安全性无法得到保障,可能会有sql注入的风险 c.数据库的创建、数据表的生成、数据备份以及数据库的迁移非常麻烦 d.sql语句性能无法保障 2.ORM框架 a.数据库:需要提前手动创建数据库 b.数据表:与ORM框架中的模型类一一对应 c.字段:模型类中的类属性(Field子类) d.记录:类似于模型类的多个实例 3.mysql中有哪些对象? a.数据库 b.数据表 c.字段 d.记录
Django进行ORM框架数据库迁移同步操作:
1.python manage.py makemigrations 子应用名(如果不指定子应用名,会把所有子应用生成迁移脚本)
2.python manage.py migrate 子应用名(如果不指定子应用名,会把所有子应用进行同步)
3.询迁移脚本生成的SQL语句:python manage.py sqlmigrate 子应用名 迁移脚本名(无需加.py)
使用时首先指定在全局配置文件settings.py中的DATABASES字典里配置需要连接的数据库信息
DATABASES = {
# 指定数据库的别名/标签
# 指定的是django默认使用的数据库
'default': {
# 指定当前使用的数据库引擎
# django.db.backends.mysql、oracle、sqlite3
'ENGINE': 'django.db.backends.sqlite3',
# 'ENGINE': 'django.db.backends.mysql',
# 指定数据库名称,如果使用的是sqlite3,需要指定sqlite3文件的绝对路径
'NAME': BASE_DIR / 'db.sqlite3',
# 'NAME': 'mydb',
# 'USER': 'root',
# 'PASSWORD': '123456',
# 'PORT': 3306,
# 'HOST': '127.0.0.1'
}
}
ORM框架进行数据库模板类的使用:
1)一般在子应用models.py中定义模型类(相当于数据库中的一张表) 2)必须继承Model或者Model的子类 3)在模型类中定义类属性(必须得为Field子类)相当于数据表中字段 4)CharField ---> varchar IntegerField ---> integer BooleanField ---> bool 5)在migrations里,存放迁移脚本: python manage.py makemigrations 子应用名(如果不指定子应用名,会把所有子应用生成迁移脚本) 6)查询迁移脚本生成的SQL语句:python manage.py sqlmigrate 子应用名 迁移脚本名(无需加.py) 7)生成的数据表名称默认为:子应用名_模型类名小写 8)默认会自动创建一个名为id的自增主键 9)在一个模型类中仅仅只能为一个字段指定primary_key=True 10)一旦在模型类中的某个字段上指定了primary_key=True,那么ORM框架就不会自动创建名称为id的主键
class Projects(models.Model):
ids = models.IntegerField(primary_key=True, verbose_name='项目主键', help_text='项目主键')
# a.CharField类型必须指定max_length参数(改字段的最大字节数)
# b.如果需要给一个字段添加唯一约束,unique=True(默认为False)
name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
unique=True)
leader = models.CharField(max_length=10, verbose_name='项目负责人', help_text='项目负责人')
# c.使用default指定默认值(如果指定默认值后,在创建记录时,改字段传递,会使用默认值)
is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目',
default=True)
# d.null=True指定前端创建数据时,可以指定该字段为null,默认为null=False,DRF进行反序列化器输入时才有效
# e.blank=True指定前端创建数据时,可以指定该字段为空字符串,默认为blank=False,DRF进行反序列化器输入时才有效
desc = models.TextField(verbose_name='项目描述信息', help_text='项目描述信息',
null=True, blank=True, default='')
# f.在DateTimeField、DateField等字段中,指定auto_now_add=True,在创建一条记录时,会自动将创建记录时的时间作为该字段的值,后续在更新数据时,就不再修改
# g.在DateTimeField、DateField等字段中,指定auto_now=True,在更新一条记录时,会自动将更新记录时的时间作为该字段的值
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
# h.可以在任意一个模型类中创建Meta内部类,用于修改数据库的元数据信息
class Meta:
# i.db_table指定创建的数据表名称
db_table = 'tb_projects'
当多个表中有共同字段时,进行创建模型类是可以先抽出共同字段方便各个模型类进行继承
class BaseModel(models.Model):
id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
class Meta:
# 在内部类Meta中,一旦指定abstract = True,那么当前模型类为抽象模型类,在迁移时不会创建表,仅仅是为了供其他类继承
abstract = True
class Projects(BaseModel):
# 在一个模型类中仅仅只能为一个字段指定primary_key=True
# 一旦在模型类中的某个字段上指定了primary_key=True,那么ORM框架就不会自动创建名称为id的主键
# ids = models.IntegerField(primary_key=True, verbose_name='项目主键', help_text='项目主键')
# id = models.AutoField(primary_key=True, verbose_name='项目主键', help_text='项目主键')
# a.CharField类型必须指定max_length参数(改字段的最大字节数)
# b.如果需要给一个字段添加唯一约束,unique=True(默认为False)
name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
unique=True)
leader = models.CharField(max_length=10, verbose_name='项目负责人', help_text='项目负责人')
# c.使用default指定默认值(如果指定默认值后,在创建记录时,改字段传递,会使用默认值)
is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目',
default=True)
# d.null=True指定前端创建数据时,可以指定该字段为null,默认为null=False,DRF进行反序列化器输入时才有效
# e.blank=True指定前端创建数据时,可以指定该字段为空字符串,默认为blank=False,DRF进行反序列化器输入时才有效
desc = models.TextField(verbose_name='项目描述信息', help_text='项目描述信息',
null=True, blank=True, default='')
# f.在DateTimeField、DateField等字段中,指定auto_now_add=True,在创建一条记录时,会自动将创建记录时的时间作为该字段的值,后续在更新数据时,就不再修改
# g.在DateTimeField、DateField等字段中,指定auto_now=True,在更新一条记录时,会自动将更新记录时的时间作为该字段的值
# create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
# h.可以在任意一个模型类中创建Meta内部类,用于修改数据库的元数据信息
class Meta:
# i.db_table指定创建的数据表名称
db_table = 'tb_projects'
# 为当前数据表设置中文描述信息
verbose_name = '项目表'
verbose_name_plural = '项目表'
ordering = ['id']
def __str__(self):
return f"Projects({self.name})"
多表进行关联
# 表与表之间有哪些关系? # Projects与Interfaces表,一对多关系 # 学生表与学生详细信息表,一对一关系 # 学生表与课程表,多对多的关系
# a.如果需要创建一对多的外键,那么会在“多”的那一个模型类中定义外键字段 # b.如果创建的是一对多的关系,使用ForeignKey # c.如果创建的是一对一的关系,可以在任何一个模型类使用OneToOneField # d.如果创建的是多对多的关系,可以在任何一个模型类使用ManyToManyField # e.ForeignKey第一个参数为必传参数,指定需要关联的父表模型类 # 方式一:直接使用父表模型类的引用 # 方式二:可以使用'子应用名称.父表模型类名'(推荐) # f.ForeignKey需要使用on_delete指定级联删除策略 # CASCADE: 当父表数据删除时,相对应的从表数据会被自动删除 # SET_NULL:当父表数据删除时,相对应的从表数据会被自动设置为null值 # PROTECT:当父表数据删除时,如果有相对应的从表数据会抛出异常 # SET_DEFAULT: 当父表数据删除时,相对应的从表数据会被自动设置为默认值,还需要额外指定default=True
class Interfaces(BaseModel):
# id = models.AutoField(primary_key=True, verbose_name='id主键', help_text='id主键')
name = models.CharField(verbose_name='接口名称', help_text='接口名称', max_length=20, unique=True)
tester = models.CharField(verbose_name='测试人员', help_text='测试人员', max_length=10)
# projects = models.ForeignKey(Projects)
# models.ManyToManyField
projects = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
verbose_name='所属项目', help_text='所属项目')
# create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
class Meta:
# db_table指定创建的数据表名称
db_table = 'tb_interfaces'
# 为当前数据表设置中文描述信息
verbose_name = '接口表'
verbose_name_plural = '接口表'
ordering = ['id']
def __str__(self):
return f"Interfaces({self.name})"