django orm 的查询条件

Django的ORM查询操作:
  查询数据库操作是一个非常重要的技术。在Django中,查询一般就是使用filter、exclude、get三个方法来实现,在调用这些方法的时候传递不同的查询条件来实现复杂的查询需求。
  在mysql中,想要查询数据,就需要使用where关键字加上字段符合的条件去查询,在Django的orm之中,我们使用filter、exclude、get这些函数加上查询条件(field+__+condition)作为关键词去查询,现在我们就来介绍一下这里的condition:

 

  1、exact:精确查询,在mysql数据库中相当于"="(如果值是None,这里就相当于is null),在这里要说明的是这个查询关键字在windows上是大小写不敏感的,其实此时加不加__exact时都一样,在Linux上当mysql的collation排序规则是utf8_bin的时候是大小写敏感的,其他时候也是大小写不敏感的:
  article = Article.objects.filter(id__exact=1)
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content` FROM `article` WHERE `article`.`id` = 1

 

  2、iexact:在mysql中相当于'like'模糊查询,但是在这里值的前后不会加上%,其实也就相当于exact,这里同样也是大小写不敏感的
  article = Article.objects.filter(id__iexact=1)
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content` FROM `article` WHERE `article`.`id` LIKE 1

 

  3、contains:在mysql中相当于'like'模糊查询,但是在这里值的前后都会加上%,意思是要查询的字段中是否包含某个字符串,这个条件过滤时是大小写敏感的,也就是转化成原生SQL的时候会在值的前面加上BINARY关键字:
  article = Article.objects.filter(title__contains='钢铁')
  原生的SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content` FROM `article` WHERE `article`.`title` LIKE BINARY %钢铁%



  4、icontains:用法和contains一样,这是在这里大消息是不敏感的
  article = Article.objects.filter(title__icontains='钢铁')
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content` FROM `article` WHERE `article`.`title` LIKE %钢铁%

 

  5、in:在mysql中对应的也是in,用于判断查询的字段在不在某个可迭代对象中,这个可迭代对象可以是一个列表,也可以是一个元祖,当然也可以是一个queryset对象
  article = Article.objects.filter(id__in=[1,2,3])
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content` FROM `article` WHERE `article`.`id` IN (1, 2, 3)

 

  6、gt/gte/lt/lte:大于/ 大于等于/ 小于/ 小于等于
  articles = Article.objects.filter(id__gte=2)
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id` FROM `article` WHERE `article`.`id` >= 2

 

  7、startswith/istartswith:以某个字符串开头,在mysql中其实也是使用like关键字,只不过值的后边加上%表示任意其他的字符串,所以这也就是查询以特定字符串开头,  startswith是大小写敏感的,istartswith则是大小写不敏感的
  articles = Article.objects.filter(title__startswith='hello')
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id` FROM `article` WHERE `article`.`title` LIKE BINARY hello%

 

  8、endswith/iendswith:以某个字符串结尾,用法与startswith/istartswith相同,这里就不赘述了

 

  9、range:对应到mysql数据库时,使用的是between... and...关键字。传递一个两个元素的元祖,用来查询字段的值介于元祖的两个元素之间的对象,元祖的两个值可以是数字,此时用来过滤数值型的字段。当然元祖的两个元素也可以是一个时间,此时则用于过滤时间类型的字段,示例代码如下:

  sTime = make_aware(datetime(year=2018,month=7,day=11,hour=10,minute=0,second=0))
  eTime = make_aware(datetime(year=2018,month=7,day=11,hour=11,minute=0,second=0))
  articles = Article.objects.filter(create_time__range=(sTime,eTime))
  原生SQL:
SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE `article`.`create_time` BETWEEN 2018-07-11 02:00:00 AND 2018-07-11 03:00:00

  10、date:过滤符合条件的年月日,如果再设置文件中设定了USE_TZ=True,那么在查询的时候orm会使用CONVERT_TZ把数据库里的UTC时间转换为你所设定的TIME_ZONE时区的时间,然后再与你的值进行比较查询。当然在mysql中默认是没有这些时区信息的,想要完成时区转换你就必须要为你的数据库添加能处理时区信息的功能,这个功能具体添加如下,访问http://dev.mysql.com/downloads/timezones.html,下载timezone_2018e_posix.zip压缩文件,将这个压缩文件中的文件解压后复制到mysql数据库的mysql文件夹中,重启mysql服务,这样mysql就可以处理时区的转换问题了。当然如果你的配置文件中设置了USE_TZ=False,那么就不需要转换时区了。
  articles = Article.objects.filter(create_time__date=datetime(year=2018,month=7,day=11))
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE DATE(CONVERT_TZ(`article`.`create_time`, 'UTC', 'Asia/Shanghai')) = 2018-07-11

 

  11、year:过滤相应的年份的数据,在SQL中使用between...and...关键字,相应的如果未使用USE_TZ,将不会有时区相关的转换。但是如果使用了USE_TZ=True,在使用的between...and...的时候,会相应的把时间从TIME_ZONE设置的时区的时间转换成UTC时区的时间,然后再去数据库中查找。示例如下:
  articles = Article.objects.filter(create_time__year=2018)
  原生SQL:article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE `article`.`create_time` BETWEEN 2017-12-31 16:00:00 AND 2018-12-31 15:59:59.999999 # setting.py文件中配置的是USE_TZ=True,TIME_ZONE="Asia/Shanghai"

 

  12、month:根据月份过滤数据,用法date相同,在将数据库里的时间使用CONVERT_TZ转换成当前时区的时间,然后再提取月份信息进行比对查询

 

  13、day:根据日期查询,用法基本与date,month一致,示例代码如下:

 

  articles = Article.objects.filter(create_time__month=3)
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE EXTRACT(MONTH FROM CONVERT_TZ(`article`.`create_time`, 'UTC', 'Asia/Shanghai')) = 3

 

 

  14、week_day:根据周几过滤数据,用法基本与date,month一致,1表示周日,2-6表示周一到周五,7表示周六

 

  15、time:根据时间过滤,如果精确到秒的话,一般与range连用

 

  16、isnull:根据是否为空进行查找,在数据库中也是IS NULL
  articles = Article.objects.filter(create_time__isnull=True)
  原生SQL:SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE `article`.`create_time` IS NULL

 

  17、regex/iregex:根据正则进行过滤,regex区分大小写,iregex不区分大小写
  articles = Article.objects.filter(create_time__regex=r'^hello')
  SELECT `article`.`id`, `article`.`title`, `article`.`content`, `article`.`category_id`, `article`.`create_time` FROM `article` WHERE `article`.`create_time` REGEXP BINARY ^hello

 

posted @ 2018-07-12 22:48  大蒙  阅读(1263)  评论(0编辑  收藏  举报