1. 程式人生 > >查詢條件筆記:(在ORM層面,查詢條件都是使用field+__+condition的方式來使用的)

查詢條件筆記:(在ORM層面,查詢條件都是使用field+__+condition的方式來使用的)

1、
exact   會被翻譯成 = 
iexact  會被翻譯成 LIKE
exact和iexact的區別,其實就是 = 和 LIKE 的區別;

article = Article.objects.get(id=14)
article = Article.objects.get(id__exact=14)
以上兩個查詢是等價的,翻譯成SQL語句如下:
select * from article where id=14

article = Article.objects.filter(title__iexact='hello world')
翻譯成SQL語句如下:
select * from article where title like 'hello world'

總結:因為 field_exact = xxx 等價於 field = xxx 而且大部分情況下 exact等價於 iexact因此我們直接使用 field = xxx 就可以了

None在SQL層面會被解釋為NULL
article = Article.objects.get(id__exact=None)
翻譯成SQL語句如下:
select * from article where id IS NULL;


2、contains:判斷某個字串中是否包含了某個元素,大小寫敏感
   icontains:判斷某個字串中是否包含了某個元素,大小寫不敏感

articles = Article.objects.filter(title__contains='hello')
翻譯成SQL語句如下:
select * where title like binary '%hello%';  (like binary代表大小寫敏感)

articles = Article.objects.filter(title__icontains='hello')
翻譯成SQL語句如下:
select * from article where title like '%hello%';

總結:contains和icontains在被翻譯成SQL的時候LIKE帶百分號;而iexact沒有百分號,那麼意味著只有完全相等的時候才會匹配到

3、in:查詢某欄位的值是否在給定的list, tuple,QuerySet物件

articles = Article.objects.filter(id__in=[1,2,3])
翻譯成SQL語句如下:
select * where id in (1,3,4)

獲取文章標題包含hello的所有分類:
list = Article.objects.filter(title__contains='hello')
categories = Category.objects.filter(article__in=list)

翻譯成SQL語句如下:
select * from category where article.id in (select id from article where title like '%hello%');

4、

gt   大於     (greater than)
gte  大於等於 (greater than equal)

lt   小於     (less than)
lte  小於等於 (less than equal)

articles = Article.objects.filter(id__gt=4)
翻譯成SQL語句如下:
select * where id > 4

5、
startswith    以xxx字串開頭的資料(大小寫敏感)
istartswith   以xxx字串開頭的資料(大小寫不敏感)

endswith      以xxx字串結尾的資料(大小寫敏感)
iendswith     以xxx字串結尾的資料(大小寫不敏感)

提取所有標題以hello字串開頭的文章
articles = Article.objects.filter(title__startswith='hello')
articles = Article.objects.filter(title__istartswith='hello')
翻譯成SQL語句如下:
select * where title like binary 'hello%'   (like binary代表大小寫敏感)
select * where title like 'hello%'

6、range(判斷某個field的值是否在給定的區間中)
提取所有釋出時間在2018/1/1到2018/12/12之間的文章:
from django.utils.timezone import make_aware
from datetime import datetime

start_date = make_aware(datetime(year=2018,month=1,day=1))
end_date = make_aware(datetime(year=2018,month=12,day=12))

articles = Article.objects.filter(createtime__range=(start_date,end_date))
翻譯成SQL語句如下:
select * from article where createtime between '2018-01-01' and '2018-12-12'

因為我們在settings.py中指定了USE_TZ=True,並且設定了TIME_ZONE='Asia/Shanghai',因此我們在提取資料的時候要使用django.utils.timezone.make_aware先將datetime.datetime從navie時間轉換為aware時間。make_aware會將指定的時間轉換為TIME_ZONE中指定的時區的時間。

7、data:根據,年月日來進行查詢(查詢時間為2018/10/10這一天發表的所有文章)
articles = Article.objects.filter(createtime__date=datetime(year=2018,month=10,day=10))
articles = Article.objects.filter(createtime__date=date(2018,10,10))
翻譯成SQL語句如下:
select * WHERE DATE(CONVERT_TZ(`article`.`createtime`, 'UTC', 'Asia/Shanghai')) = 2018-10-10

8、time:根據,時分秒進行查詢
以上的程式碼是獲取每一天中12點12分12秒發表的所有文章
articles = Article.objects.filter(createtime__time=datetime.time(12,12,12));

9、year/month/day   根據,年/月/日,進行查詢(year/month/day 用法都相同,下面只列舉了year的用法)
查詢2018這一年發表的所有文章:
articles = Article.objects.filter(createtime__year=2018)
翻譯成SQL語句如下:
select * where createtime between '2018-01-01' and '2018-12-31';

查詢年份大於等於2017,發表的所有文章:
articles = Article.objects.filter(createtime__year__gte=2017)
翻譯成SQL語句如下:
select * where createtime >= '2017-01-01';

10、week_day  根據星期來進行查詢,1->星期日,7->星期六
查詢星期五,發表的所有文章:
articles = Article.objects.filter(createtime__week_day=4)
翻譯成SQL語句如下:
SELECT * WHERE django_datetime_extract('week_day', "article"."createtime", 'Asia/Shanghai') = 4

11、isnull:根據值是否為空進行查詢(設定成True為空,False不為空)
獲取所有釋出日期不為空的文章
articles = Article.objects.filter(pub_date__isnull=False)
翻譯成SQL語句如下:
select * where createtime is not null

12、
regex   寫正則表示式去查詢(大小寫敏感)
iregex  寫正則表示式去查詢(大小寫不敏感)

提取所有標題以hello字串開頭的文章
articles = Article.objects.filter(title__regex=r'^hello')
翻譯成SQL語句如下:
select * where title regexp binary '^hello'