美文网首页
9、Django_ORM_数据的创建以及增删改查

9、Django_ORM_数据的创建以及增删改查

作者: 猪儿打滚 | 来源:发表于2019-10-06 16:57 被阅读0次

一、查询集QuerySet

  • 什么是查询集?
    查询集:从数据库查询得到的模型对象集合QuerySet,是一个列表
  • 什么是过滤器?
    过滤器:基于查询集得到的结果上进一步进行条件筛选过滤结果

二、过滤器

返回list/多个结果的过滤器
  • values = model名称.objects.all():返回所有数据;返回查询集QuerySet对象。因为是列表,所以其结果可以使用values[索引].字段名获取数据。注意不支持负索引
  • model名称.objects.retrieve():获取数据表中的所有记录,也就是返回查询集QuerySet对象
  • model名称.objects.filter():返回满足条件的数据
  • model名称.objects.exclude():返回满足条件之外的数据
  • model名称.objects.order_by():返回排序后的结果
返回一个对象的过滤器
  • model名称.objects.get():返回一个model类,而不是str
    1.如果查询不到对应的结果, 则会抛出模型类.DoesNotExist异常
    2.如果返回多条结果,则会抛出模型类.MultipleObjectsReturned异常
  • model名称.objects.count():返回满足查询结果的总条数
  • model名称.objects.aggregate():返回集合
  • model名称.objects.exists():判断返回的查询集中是否有数据,没有则False,有则True
    PS.
    1.过滤器往往会和查询条件结合使用进行查询
    2.一般情况用 model名称.objects,但也会指定对象,比如说polls.address.
查询集的特点
  • 非立刻执行
    1.创建查询集时,并不会访问数据库。而是直到模板中调用到数据时,才会进行数据库的访问。
  • 缓存
    1.查询集的结果会被保存下来,再次查询相同的数据时,会使用之前保存下来的结果数据
    2.每个查询集都会有一个缓存空间来保存查询结果数据
    3.切片和索引操作没有缓存可用,每次都会实际去执行sql语句
查询集索引

当查询集返回的是列表时,就可以使用下标的方式来获取我们想要的内容。

def AddressAPI(request):
    # 获取第2、3、4项
    address_values = AddressInfo.objects.all()[1:3]
    # 构造上下文
    context = {F'AddressInfo:{address_values}'}
    return render(request, 'address.html', context)

三、查询集的查询条件

  • 查询语句:模型属性/表字段__条件运算符=值
    1.查询语句由三部分组成:模型属性/表字段+两个下划线__+条件运算符,所以在定义属性模型/表字段时,不能定义包括多个下划线的名字
    2.想要实现SQL中的where功能,可以使用过滤器filter()exclude()get()
  • 条件运算符
    1.exact:判断相等
address = AddressInfo.objects.filter(id__exact = 1)  # 查询id为1的地址

2.contains:判断包含

address = AddressInfo.objects.filter(name__contains = '广')  # 查询地址名称有广的地址

3.startswith/endswith:以什么开头/结尾
4.isnull:是否为null

address = AddressInfo.objects.filter(pid__isnull = true)  # 查询pid为null的地址

5.in:是否包含在范围内

address = AddressInfo.address.filter(id__in = [1,3])  # 查询id为1或3的地址

6.gt、gte、lt、lte:大于、大于等于、小于、小
7.exclude:条件以外的数据

address = AddressInfo.objects.filter(id__exclude = 1)   # 查询id不为1的地址

8.year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行查询

books = BookInfo.objects.filter(pub_time__year = 2000)  # 查询2000年发表的书籍

9.datetime.date

from datetime import date
books = BookInfo.objects.filter(pub_time__gt = date(2000,1,1))  # 查询2000年1月1号以后发布的书籍

10.多条件查询:或(使用|隔开查询条件)

BookInfo.objects.filter(id__gt = 1 | pub_time__year = 2000)  # 查询id大于1或发布年份是2000年的数据

11.多条件查询:与(使用,隔开查询条件)

BookInfo.objects.filter(id__gt = 1 , pub_time__year = 2000)  # 查询id大于1,并且发布年份是2000年的数据

12.链式查询:多个filter()进行查询(其它过滤器也可以这样)

BookInfo.objects.filter(id__gt = 1).filter(pub_time__year = 2000) # 在查询id大于1的结果集上,再查询发布年份是2000年的数据

13.获取查询集的第一个元素以及最后一个元素:first()last()

BookInfo.objects.filter(id__gt = 1).first()
BookInfo.objects.filter(id__gt = 1).last()

14.排序order_by('字段/-字段')

BookInfo.objects.filter(id__gt = 1).order_by('name') # 结果按照name排序,ascall码从小到大
BookInfo.objects.filter(id__gt = 1).order_by('-name') # 结果按照name排序,ascall码从大到小
BookInfo.objects.filter(id__gt = 1).order_by('id', 'name') # 结果先按照id排序,如果相同,则按照name排序

PS.
1.exact、contains、startswith、endswith这几个运算符都区分大小写,如需不区分大小写,只需要在前面加上i即可:iexact、icontains、istartswitch、iendswith

四、F对象和Q对象

  • F对象用于两个属性进行比较,并且支持运算
    1.语法:
from django.db.models import F
F("属性名/表字段")

2.例子
2.1.查询评论量大于阅读量的书籍

books = BookInfo.objects.filter(commentcount__gt = F('readcount'))

2.2.查询评论量大于阅读量2倍的书籍

books = BookInfo.objects.filter(commentcount__gt = F('readcount' * 2))
  • Q对象类似sql语句的where中的andor
    1.语法
from django.db.models import Q
# |:或
Q(属性名/表字段1__条件运算符=值) |  Q(属性名/表字段2__条件运算符=值)   # 查询满足第一个条件或第二个条件的数据
# ,:且
Q(属性名/表字段1__条件运算符=值) ,  Q(属性名/表字段2__条件运算符=值)  # 查询满足第一个条件和第二个条件的数据
# 组合
Q(属性名/表字段1__条件运算符=值) ,  Q(属性名/表字段2__条件运算符=值)  |  Q(属性名/表字段3__条件运算符=值)  # 查询满足条件1且(条件2或条件3)的数据

2.1.或:|

books = BookInfo.objects.filter(Q(readcount__gt = 10) | Q(id__lt) = 5)  # 查询阅读量大于10或id小于5的书籍

2.2.且:,

books = BookInfo.objects.filter(Q(readcount__gt = 10) , Q(id__lt) = 5)  # 查询阅读量大于10且id小于5的书籍

2.3.不等于/取反:~

books = BookInfo.objects.filter(~Q(readcount__gt = 10) , Q(id__lt) = 5)  # 查询阅读量小于等于10且id小于5的书籍

2.4.组合

PS.如果有其它关键字条件,Q对象需要在关键字条件后面

books = BookInfo.objects.filter(pub_time = 2000 , Q(id__lt) = 5)  # pub_time是关键字

关于Q对象更详细看文章:https://www.cnblogs.com/huchong/p/8027962.html

五、聚合函数

  • aggregate()过滤器调用聚合函数,然后返回单个对象
  • 聚合函数:Avg('属性名/表字段')Max('属性名/表字段')Min('属性名/表字段')Sum('属性名/表字段')Count('属性名/表字段')。使用Count('属性名/表字段')时,一般情况下是直接调用,不需要使用aggregate()函数
  • 聚合函数在django.db.models导入
  • 例子(注意上下文字典中,总阅读量的key的书写规则)
from django.db.models import Sum

def books(request):
    # 统计所有书籍的总阅读量
    readcount = BookInfo.objects.aggregate(Sum('readcount'))
    # 构造上下文
    context = {'readcount': readcount}
    return  render(request, 'Book/book.html', context)

六、关联查询(objects前面用的是哪个class,返回的就是哪个class对象)

一对多、多对多关联查询(基础关联)
  • 查询方老师所教的所有课程
 # 先查询方老师
teacher = Teacher.objects.get(nickname = '方老师')
# 再通过方老师查询所有相关的任务信息
classInfo = teacher.classinfo_set.all()
  • 查询python课程的老师
# 先查询课程
class = ClassInfo.object.get(title = 'python课程')
# 再通过关联查询对应的老师
teacher = class.teacher
内连接查询
  • 语法:外键字段名__从表字段名__条件关联模型类名小写__属性名__运算符=值,结果和sql中的inner join相同(内连接)
  • 查询书名为"红楼梦"的所有人物信息(peopleInfo)
    通过书找关联的人
# 原始内连接sql语句:
select p.name, b.name from peopleinfo as p inner join bookinfo as b on p.book_id = b.id where b.name = "红楼梦";

对应语句:

peopleInfos = PeopleInfo.objects.filter(book__name='红楼梦')
  • 查询书籍中人物的描述包含"红"的书籍
    通过人找关联的书
bookInfos = BookInfo.books.filter(peopleinfo__description__contains='红')
自关联查询

自关联的表结构:对于地区信息、分类信息等数据,表结构非常类似,每个表的数据量十分有限,为了充分利用数据表的大量数据存储功能,可以设计成一张表,内部的关系字段指向本表的主键
说明:关系属性使用self指向本类,要求null和blank允许为空,因为一级数据是没有父级的
更多看之前的文章:https://www.jianshu.com/p/08c1be3dc9b2

七、LIKE语句中转义百分符号和下划线

在sql语句中,%有特殊的作用,Django可以转义%_,这样就可以和普通字符一样使用

xxx.objects.filter(headline__contains='%')
# 相当于sql:
SELECT ... WHERE headline LIKE '%\%%';

八、创建数据/生成数据表中的数据

  • 创建和保存对象
#### 方法1
# 1.创建模型类对象,此时sql还未执行
one_value = Userinfo(username='hello', password='hi')
# 2.调用save方法,执行sql语句,生成数据
one_value.save()

#### 方法2
# 执行sql语句,生成数据,返回的是模型类对象
Userinfo.objects.create(username='hi', password='hello')
  • 保存外键字段
    保存外键字段和保存普通字段一样,只不过给外键字段赋值的时候迅速要注意类型要正确
  • 保存多对多字段
    需要调用add()方法,而不是直接给属性赋值,不过不需要调用save()方法
from .model.animal import Animal
from .model.cat import Cat

animal = Animal.objects.get(pk = 1)
cat1 = Cat.objects.create(named='xiaomi')  
cat2 = Cat.objects.create(named='xiaohei')

animal.cats.add(cat1, cat2)    # 保存多对多字段

八、修改数据和更新数据

  • 修改数据:先获取数据,然后修改数据,再保存数据(一般用于外键/ForeignKey的修改)
value = Animal.objects.get(id=1)
value.namede = 'haha'
value.save()
  • 更新数据:update()
    1.可以批量为QuerySet中所有的对象进行更新操作
    2.只能对普通字段和ForeignKey字段使用
    3.对ForeignKey字段使用时,需要设置新值为想要指向的新模型实例
# 普通字段
Animal.objects.filter(id=1).update(named = 'hahaha')
# ForeignKey字段
c = Cat.objects.get(id=2)  # 想要指向的新模型实例
Animal.objects.all().update(cat=c)
  • update()方法会直接转换成一个sql语句,并立刻批量执行,并且不会运行模型的save()方法。如果想要保存QuerySet中的每个条目并确保每个实例的save()方法都被调用,你不需要使用任何特殊的函数来处理。只需要迭代它们并调用save()方法:
for item in my_queryset:
    item.save()
  • update方法可以配合F表达式。这对于批量更新同一模型中某个字段特别有用。例如增加Blog中每个Entry的pingback个数:
    Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)。然而,与filterexclude子句中的F()对象不同,在update中不可以使用F()对象进行跨表操作,只可以引用正在更新的模型的字段。如果尝试使用F()对象引入另外一张表的字段,将抛出FieldError异常:
# THIS WILL RAISE A FieldError
>>> Entry.objects.update(headline=F('blog__name'))

九、删除数据

先获取数据,再删除数据

value = Animal.objects.get(id=1)
value.delete() # 该方法将返回被删除对象的总数量和一个字典,字典包含了每种被删除对象的类型和该类型的数量
# 支持批量删除
Animal.objects.filter(named='haha').delete()
  • 注意
    delete()是唯一没有在管理器上暴露出来的方法。这是刻意设计的一个安全机制,用来防止意外地请求类似Animal.objects.delete()的动作,导致不慎删除了所有的对象数据。如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集,如:
Animal.objecets.all().delete()

PS.本文参考:
https://blog.csdn.net/kan2016/article/details/82868636/https://www.cnblogs.com/huchong/p/8027962.html

相关文章

  • 9、Django_ORM_数据的创建以及增删改查

    一、查询集QuerySet 什么是查询集?查询集:从数据库查询得到的模型对象集合QuerySet,是一个列表 什么...

  • 数据库的存储

    如何创建数据库 数据库的增删改查 增insert into student (name,phone) values...

  • Mysql SQL语句整理

    前言 以下主要针对数据库简单的增删改查等常用sql语句做了简单的整理! 具体语法: 增 1、创建用户 2、创建数据...

  • nodejs+mongodb

    nodejs操作 mongodb数据库增删改查 创建node增删改查执行文件

  • 2018-06-23 (数据库)

    /*表的增删改查增创建删除删除整张表改改变表名改变列名改变列类型查查询表结构查询表信息表数据的增删改查增插入指定列...

  • python列表操作方法集合

    本文集合了python中对List列表类型数据的创建和排序、以及List内数据增删改查等操作方式。 List创建 ...

  • 关于python的list的增查删改

    说到增查删改,想起了数据库,我们在关系型数据库当中就会对表进行增查删改。 在python当中我们也可以对list进...

  • MYSQL数据库的增删改查

    MYSQL数据库的增删改查 一.对于库的增删改查 增create database 库名称;create data...

  • IOS FMDB的简单实用

    对数据库简单的操作: 增删改查 1、确定存储的路径,并创建文件 打开文件,并创建表 3.增: 往表中添加数据 ...

  • Nodejs+Mongodb

    nodejs操作 mongodb数据库增删改查 创建node增删改查执行文件 有闪电

网友评论

      本文标题:9、Django_ORM_数据的创建以及增删改查

      本文链接:https://www.haomeiwen.com/subject/yvchpctx.html