django模型——ORM模型2
一、查询集
在这里我随便拿个项目进行下列操作
返回列表的过滤器如下:
all():返回所有数据
filter():返回满足条件的数据
exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字
order_by():排序,参数为字段名,-号表示降序
views.py
post_list1 = Post.objects.all()[1:] # all():返回所有数据 print('返回所有数据:',post_list1) post_list2 = Post.objects.filter(is_delete=True) #filter():返回满足条件的数据 返回已经逻辑删除的文章 print('返回已经逻辑删除的文章:',post_list2) post_list3 = Post.objects.exclude(is_delete=True) #filter():返回不满足条件的数据 返回没有逻辑删除的文章 print('返回没有逻辑删除的文章:',post_list3) post_list4 = Post.objects.exclude(is_delete=True).order_by('pub_time') #order_by():排序,参数为字段名,-号表示降序 print('按照发布时间升序排序:',post_list4) post_list5 = Post.objects.exclude(is_delete=True).order_by('-pub_time') #order_by():排序,参数为字段名,-号表示降序 print('按照发布时间降序排序:',post_list5) post_list6 = Post.objects.filter(category__category_name="言情小说") print('言情小说:',post_list6)
结果:
返回单个值的过滤器如下:(对象)
get():返回单个满足条件的对象。如果未找到会引发"模型类.DoesNotExist"异常
如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常
count():返回当前查询的总条数 exists():判断查询集中是否有数据,如果有则返回True,没有则返回False
views.py
p1 = Post.objects.get(id=1) #获取对象 print('p1:',p1) p2 = Post.objects.first() #获取第一个 print('p2:',p2) p_count = Post.objects.filter(is_delete=False).count() #获取没有被逻辑删除对象的数量 print('p_count:',p_count) is_exi = Post.objects.filter(content='hhh').exists() #exists():判断查询集中是否有数据,如果有则返回True,没有则返回False print('is_exi:',is_exi) #False
返回结果:
限制查询集:
查询集返回列表,可以使用下标的方式进行限制,等同于sql中的limit和offset子句,不支持负数索引。
使用下标后返回一个新的查询集,不会立即执行查询 如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常。
views.py
p=Post.objects.all()[0:2] print('获取第1、2条数据:',p) print('利用下标获取查询集第一个数据对象:',p[0])
返回结果:
返回列表的过滤器演示:
# filter():返回满足条件的数据 # 查询分类为'耽美小说'的文章 post_list = Post.objects.filter(category__category_name="耽美小说") print('耽美小说:',post_list) # exclude():返回满足条件之外的数据 # 查询分类不是'耽美小说'的数据 post_list = Post.objects.exclude(category__category_name="耽美小说") print('非耽美小说:', post_list)
二、数据查询
1.基本查询
exact:表示相等
contains:是否包含startswith、endswith:以指定值开头或结尾iexact,icontains,istartswith,iendswith功能同上面四个一样,前面加字母i表示不区分大小写。isnull:是否为nullin:是否包含在范围内gt:大于 gte:大于等于lt:小于 lte:小于等于
#exact:表示相等 p_lis1 = Post.objects.filter(title__exact='我是曹操1') print('p_lis1:',p_lis1) #contains:是否包含 p_lis2 = Post.objects.filter(title__contains='我是') print('p_lis2',p_lis2) p_lis3 = Post.objects.filter(title__icontains='python') #icontains不区分大小写 print('p_lis3',p_lis3) # startswith、endswith:以指定值开头或结尾 p_lis4 = Post.objects.filter(title__startswith='我是') print('p_lis4', p_lis4) p_lis5 = Post.objects.filter(title__endswith='我是') print('p_lis5', p_lis5) #in:是否包含在范围内 p_lis6 = Post.objects.filter(id__in=[2,4,7]) print('p_lis6', p_lis6) #isnull:是否为null p_lis7 = Post.objects.filter(title__isnull=False) print('p_lis7', p_lis7) # gt:大于 p_lis8 = Post.objects.filter(id__gt=5) print('p_lis8', p_lis8) # gte:大于等于 p_lis9 = Post.objects.filter(id__gte=5) print('p_lis9', p_lis9) # lt:小于 p_lis10 = Post.objects.filter(id__lt=5) print('p_lis10', p_lis10) # lte:小于等于 p_lis11 = Post.objects.filter(id__lte=5) print('p_lis11', p_lis11) p_lis12 = Post.objects.exclude(id__lte=5) print('p_lis12', p_lis12)
exclude()方法:返回满足条件之外的数据,实现不等于效果year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算F对象 专门取对象中某列值的操作,F() 返回的实例用作查询内部对模型字段的引用。这些引用可以用于查询的filter 中来比较相同模型实例上不同字段之间值的比较。Q对象 逻辑运算
#year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算 p_lis1 = Post.objects.filter(pub_time__year=2023) # p_lis1 = Post.objects.filter(pub_time__month=10) print('p_lis1:', p_lis1) # 思考1:在10月5日之前,10月1号之后的文章并且标题包含“我是”的文章怎么获取? p_lis2 = Post.objects.filter(pub_time__gte=datetime.datetime(2023,10,1,0,0,0)).filter(pub_time__lte=datetime.datetime(2023,10,5,0,0,0)).filter(title__contains='我是') print('p_lis2:', p_lis2) #上面的写法,同时满足多个条件,我们可以简写如下 p_lis3 = Post.objects.filter(pub_time__gte=datetime.datetime(2023,10,1,0,0,0),pub_time__lte=datetime.datetime(2023,10,5,0,0,0),title__contains='我是') print('p_lis3:', p_lis3) #上面的写法,同时满足多个条件,我们还可以简写如下: Q p_lis4 = Post.objects.filter(Q(pub_time__gte=datetime.datetime(2023,10,1,0,0,0)) & Q(pub_time__lte=datetime.datetime(2023,10,5,0,0,0)) & Q(title__contains='我是')) print('p_lis4:', p_lis4) #思考2:获取id为2,4,5 或者 标题含有 “python”文章 #&表示并且 |表示或者 ~表示非 p_lis5 = Post.objects.filter(Q(id__in=[2,4,5]) | Q(title__icontains='python')) print('p_lis5:', p_lis5) p_lis6 = Post.objects.filter(Q(Q(id__in=[2,4,5]) | Q(title__icontains='python')) & Q(pub_time__gte=datetime.datetime(2023,10,5,0,0,0)) ) print('p_lis6:', p_lis6) #思考3: 如何获取用户修改过一遍的文章呢? (modify_time大于pub_time) #对实例本身的两个字段进行比较: F p_lis7 = Post.objects.filter(modify_time__gt=F("pub_time")) print('p_lis7:', p_lis7)
2.关联查询
#思考4:想获取所有分类为“言情小说” # p_lis = Post.objects.filter(category='言情小说')#不行 #方法1 yqxs = Category.objects.get(category_name__exact='言情小说') p_lis1 = Post.objects.filter(category_id=yqxs.id)#虽然可行,很麻烦 print('方法1:',p_lis1) #推荐方法2:一对多中的1去查 p_lis2 = Post.objects.filter(category__category_name='言情小说') print('方法2:',p_lis2)
3.反向查询
#推荐方法3:一对多中的多去查 yqxs= Category.objects.get(category_name__exact='言情小说') p_lis1 = yqxs.post_set.all() print('方法3:',p_lis1) nice = Tag.objects.get(name='nice') p_lis2 = nice.post_set.all() print('获取标签为nice的小说:',p_lis2)
4.聚合函数
# 使用aggregate() # 过滤器调用聚合函数, 常用聚合函数:Avg,Count,Max,Min,Sum,被定义在 # django.db.models中 # 需要使用要先导入聚合函数 # 聚合函数返回结果是一个字典: #如何获取用户修改过一遍的文章中最大id和最小id idmax = Post.objects.filter(modify_time__gt=F("pub_time")).aggregate(Max('id')) idmin= Post.objects.filter(modify_time__gt=F("pub_time")).aggregate(Min('id')) print('取用户修改过一遍的文章中最大id:',idmax) print('取用户修改过一遍的文章中最小id',idmin)