我们配置了ORM框架并初步创建了简单的模型类,接下来可以把之前的模型类进行优化
projects应用中的model.py,增加一些新的属性
class ProjectsModel(BaseModel): # 设置id为主键 id = models.AutoField(primary_key=True, verbose_name="id主键", help_text="id主键") name=models.CharField(max_length=200,verbose_name="项目名",help_text="项目名") leader=models.CharField(max_length=20,verbose_name="负责人",help_text="负责人") tester=models.CharField(max_length=20,verbose_name="测试",help_text="测试") programmer=models.CharField(max_length=50,verbose_name="开发人员",help_text="开发人员") publish_app=models.CharField(max_length=100,verbose_name="发布应用",help_text="发布应用") desc=models.TextField(max_length=200,verbose_name="简要描述",help_text="简要描述",blank=True,null=True,default="") class Meta: db_table = 'tb_projects' verbose_name = '项目信息' verbose_name_plural = verbose_name def __str__(self): # a.必须返回一个字符串类型 # b.在打印模型类对象时,会自动调用 return self.name
再创建新应用interfaces,并且在全局配置表中进行注册
在models.py中定义类属性:
class InterfacesModel(BaseModel): # 在关系型数据库中,有哪些关联关系? # a.一对一 # b.一(父表)对多(子表、从表) # c.多对多 id = models.IntegerField(primary_key=True, verbose_name="id主键", help_text="id主键") name = models.CharField(max_length=200, verbose_name="接口名称", help_text="接口名称") tester = models.CharField(max_length=200, verbose_name="测试人员", help_text="测试人员") # a.可以使用ForeignKey来指定一对多的外键字段 # b.需要在“多”的那一侧添加外键字段 # c.第一个必传参数需要添加关联的父表,有两种添加方式: # 方式一,可以直接使用父表模型类 # project = models.ForeignKey(ProjectsModel, on_delete=models.CASCADE) # 方式二,可以使用字符串(子应用名.父表模型类名) # d.第二个必传参数,需要on_delete指定删除父表记录时的子表该字段的处理方式 # CASCADE指定为当父表中某条记录删除之后,父表中这条记录所属的从表记录,会自动被删除 # SET_NULL指定为当父表中某条记录删除之后,父表中这条记录所属的从表记录,会自动设置为空,需同时设置null=True # PROTECT指定为当父表中某条记录删除之后,会报错 # e.数据表中,会创建名称为外键字段_id的字段名 project = models.ForeignKey("projects.ProjectsModel", on_delete=models.CASCADE) # models.OneToOneField指定一对一的外键字段 # models.ManyToManyField指定多对多的外键字段 class Meta: db_table = "tb_interfaces" verbose_name = "接口表" def __str__(self): return self.name
先使用命令行造个数据(在pycharm中的Python Console控制台输入命令)
导入模型类
from projects.models import ProjectsModel
实例化模型类
res=ProjectsModel(name="111",leader="测试leader",tester="测试人",programmer="五星开发",publish_app="发布应用",desc="没有描述信息")
保存
res.save()
在视图函数里创建数据(create)
方法一:
执行之后创建了数据
说明:
- 创建了模型类对象后,还没有执行sql语句
- 必须要调用模型类对象.save()方法,才会执行sql语句并创建数据
方法二:
可以调用模型类.objects.create() 方法区创建模型类对象(一条记录)
data=ProjectsModel.objects.create(name="是个名字a a ",leader="测试leader",tester="测试人",programmer="五星开发",publish_app="发布应用",desc="没有描述信息")
- 调用模型类.objects返回是的Manager对象 ,我们以后对数据库的操作,都可以在Manager基础上去操作
- 然后调用Manger对象的create()方法,去创建模型类对象
- 与方法一相比,无需再单独调用save()方法
数据的查询 (read)
方式一
查询某一条记录
- 如果查询条件是唯一键(比如主键id、unique=True的字段)
- 如果可以查到---->返回结果
- 如果查不到----->抛出异常
- 如果查询条件不是唯一键---->会抛出异常
- ORM中主键id字段,拥有一个pk别名
one_project = Projects.objects.get(pk=1)
使用id主键查询:
data=ProjectsModel.objects.get(id=1)
可以查询导数据:
如果使用非唯一键查询:就会抛出异常
查询多条记录
查询多条数据的时候我们可以调用all()方法,可以查询所有数据,返回的是一个查询集queryset
data_query=ProjectsModel.objects.all()
方式二
还可以使用filter过滤,返回的是一个查询集queryset
a.可以使用filter()方法,对数据库中的记录进行过滤(搜索)
b.会将满足条件的结果(模型类对象),添加到查询集中并返回
id__gte=2 (id >= 2)
id__in=[1, 2]
one_qs = Projects.objects.filter(name__contains='2')
c.调用filter方法,可以使用各种过滤表达式参数
d.字段名__表达式可以对数据进行过滤(查询)
e.过滤表达式有很多种
字段名__lt: <
字段名__lte: <=
字段名__gt: >
字段名__gte: >=
字段名__in: 包含某些值,使用序列类型(list、tuple)
字段名__contain: 包含子字符串 字段名__icontain: 包含子字符串(忽略大小写)
字段名__startswith: 包含以子字符串开头 字段名__istartswith: 包含以子字符串开头(忽略大小写)
字段名__endswith: 包含以子字符串结尾 字段名__endswith: 包含以子字符串结尾(忽略大小写)
1、one_qs = Projects.objects.filter(id=2) 2、one_qs = Projects.objects.filter(id__exact=2) 3、one_qs = Projects.objects.filter(pk=2) 4、one_qs = Projects.objects.filter(id__in=[1, 2]) 5、one_qs = Projects.objects.filter(name__startswith='x') 6、one_qs = Projects.objects.filter(name__contains='2')
其中1和2是等价的
one_qs = Projects.objects.filter(name__contains='2', desc__startswith='y') one_qs = Projects.objects.filter(name__contains='2').filter(desc__startswith='y') one_qs = Projects.objects.filter(name__contains='2').exclude(desc__startswith='x') one_qs = Projects.objects.filter(Q(name__contains='3') | Q(desc__startswith='y'))
说明:
a.如果同一个filter方法中,添加多个过滤条件,那么每个条件之间为“与”的关系
b.查询集对象支持链式调用,可以在查询集对象上,多次调用filter
c.查询集链式调用,每个条件直接为“与”的关系
下面使用Q查询中,多个Q对象之间如果使用“|”,每个条件之间为“或”关系
one_qs = Projects.objects.filter(Q(name__contains='项目') | Q(leader='测试leader'))
查询集queryset对象支持哪些操作呢??
查询集支持的操作:
- 支持列表中的多数操作
- len(qs) 获取查询集个数,推荐使用qs.count()方法
- 切片 qs[a:b] 返回的依然为查询对象
- qs[真整数索引],不支持负值索引
- qs[0],推荐使用qs.first()方法
- qs[qs.count() - 1],推荐使用qs.last()方法
- qs.exist()方法,判断查询集是否为空,如果为空,返回False,否则返回True
- list(qs),将查询集对象转化为列表
- 查询集支持for操作,每次迭代返回模型类对象
- 查询集为了增加性能,实现惰性查找的机制(只有真正需要数据的时候,才会执行sql语句)
- 支持链式调用,可以多次调用filter或者exclude方法
- 可以使用exclude将不满足条件的所有结果返回
- one_qs = Projects.objects.exclude(id=1)
数据的更新(update)
方式一
a.更新一条数据,可以先将数据查询出来,返回模型类对象
b.然后直接修改模型类对象的属性值
c.模型类对象调用save()方法,保持数据
pro = Projects.objects.get(pk=2) pro.name = 'xxx金融类项目' pro.save() one_dict = { "id": pro.id, "name": pro.name }
方式二
可以使用filter方法().update(),批量修改多条数据
obj = Projects.objects.filter(Q(name__contains='2') | Q(name__contains='3')).update(leader='潇潇')
数据的删除(delete )
先将需要删除的模型类对象查询出来,然后调用delete()方法
one_obj = Projects.objects.get(id=2) one_obj.delete()
数据的排序操作
a.可以在查询集对象上调用.order_by()方法,可以对查询集中的模型类对象进行排序
b.order_by()方法,可以添加需要排序的字段名称,默认为升序(asc)
c.可以在字段名称前添加“-”,进行降序排列(desc)
e.如果有多个排序字段,可以给order_by()方法添加多个位置参数
f. 如果排序方法中存在多个相同字段的排序,则会以第二个字段的排序决定如何排序
下面的排序意思是:查询出来的数据通过id降序,name升序展示出来
qs = Projects.objects.all().order_by('-id','name')