models查询功能就是对数据库进行检索,Django的 ORM 自带有很多检索方法来简化 select 语句。
检索所有对象
ret = User.objects.all()
all ( ) 方法会以queryset(类似于列表)的形式返回该数据库中所有的数据。
检索单个对象
ret = User.objects.get(pk=1)
get ( ) 方法返回的是符合条件的单个数据,适合检索唯一性数据
如果没有匹配的对象会触发 DoesNotExist
异常
如果匹配到多条数据会触发MultipleObjectsReturned
异常
检索特定对象
使用过滤器来检索特定对象主要有 filter 与 exclude 两种方法,与 all 相同返回的都是一个数据集合。没有数据匹配到返回一个空集合。
#查找符合条件的选项
ret = User.objects.filter(password="123456")
#查找不符合条件的选项
ret = User.objects.exclude(password="123456")
过滤器是可以叠加操作的,比如
ret=User.objects.exculde(password="123456").filter(password="654321")
每一步的过滤都会产生一个独立的全新的queryset对象。
在过滤的过程中,相关语句并不会涉及任何 数据库相关操作,只有在使用queryset结果时才会执行操作。
filter 可以针对字段来进行条件查询
- 对象__字段=value:外键某个字段为value的
- 字段__exact=value:该字段为value(区分大小写)的
- 字段__iexact=value:该字段为value(忽略大小写)的
- 字段__contains=value:该字段包含value的
- 字段__icontains=value:该字段包含value(忽略大小写)的
- 字段__lt=value:该字段小于value的
- 字段__lte=value:该字段小于等于value的
- 字段__gt=value:该字段大于value的
- 字段__gte=value:该字段大于等于value的
- 字段__in=list:该字段存在于list的
- 字段__startswith=value:该字段以value开头的
- 字段__istartswith=value:该字段以value(忽略大小写)开头的
- 字段__range=value:该字段在value范围的
- 字段__year=value:该字段等于value年的
- 字段__month=value:该字段等于value月的
- 字段__day=value:该字段等于value日的
- 字段__isnull=True/False:该字段为空或非空的
对查询结果进行切片
queryset结果是类列表结构,针对列表的一些方法也是可以使用的,比如:
ret[:5] # 查询结果前五条数据
ret[-5:] # 查询结果后五条数据
ret[::2] # 查询结果第单数个数据
ret[1:-1:2] # 查询结果第双数个数据
...
获取某一字段的所有值
values()方法可以帮助我们获取某一字段的所有值,参数就是字段名
比如获取所有用户的昵称
ret = User.objects.values('nickname')
# 返回的是一个字典列表 [{'nickname':u'goudan'},{'nickname':'goushen'}]
ret = User.objects.values_list('nickname')
# 返回的是一个元组列表 [(u'goudan',), ('goushen',)]
ret = User.objects.values_list('nickname',flat=True)
# 返回的是一个元组列表 [u'goudan', 'goushen']
对查询结果去重
distinct()方法可以对查询结果进行字段去重
Django中ORM查询的性能问题
执行查询操作后,queryset将会被缓存起来,再次使用时是从缓存中取数据,这样避免了大量重复的请求影响数据库的性能。
当需要判断queryset是否为空,可以由以下方式判断,性能依次增加:
if ret:pass
if ret.count>0:pass
if ret.exists():pass
当获取的数据非常大时,可以用迭代的方式取值:
ret.iterator()