- exact:在底層會(huì)被翻譯成
=。
-
iexact:在底層會(huì)被翻譯成
LIKE。LIKE和=:大部分情況下都是等價(jià)的,只有少數(shù)情況下是不等價(jià)的。
exict和iexact:他們的區(qū)別其實(shí)就是LIKE和=的區(qū)別,因?yàn)閑xact會(huì)被翻譯成=,而iexact會(huì)被翻譯成LIKE。
因?yàn)?code>field__exact=xxx其實(shí)等價(jià)于
filed=xxx,因此我們直接使用filed=xxx就可以了,并且因?yàn)榇蟛糠智闆rexact和iexact又是等價(jià)的,因此我們以后直接使用field=xxx就可以了。
- QuerySet.query:
query可以用來(lái)查看這個(gè)ORM查詢語(yǔ)句最終被翻譯成的SQL語(yǔ)句。但是query只能被用在QuerySet對(duì)象上,不能用在普通的ORM模型上。因此如果你的查詢語(yǔ)句是通過(guò)get來(lái)獲取數(shù)據(jù)的,那么就不能使用query,因?yàn)?code>get返回的是滿足條件的ORM模型,而不是QuerySet。如果你是通過(guò)filter等其他返回QuerySet的方法查詢的,那么就可以使用query。
- contains:使用大小寫敏感的判斷,某個(gè)字符串是否在指定的字段中。這個(gè)判斷條件會(huì)使用大小敏感,因此在被翻譯成
SQL語(yǔ)句的時(shí)候,會(huì)使用like binary,而like binary就是使用大小寫敏感的。
icontains:使用大小寫不敏感的判斷,某個(gè)字符串是否被包含在指定的字段中。這個(gè)查詢語(yǔ)句在被翻譯成
SQL的時(shí)候,使用的是like,而like在MySQL層面就是不區(qū)分大小寫的。contains和icontains:在被翻譯成
SQL的時(shí)候使用的是%hello%,就是只要整個(gè)字符串中出現(xiàn)了hello都能過(guò)夠被找到,而iexact沒(méi)有百分號(hào),那么意味著只有完全相等的時(shí)候才會(huì)被匹配到。
-
in:可以直接指定某個(gè)字段的是否在某個(gè)集合中。示例代碼如下:
articles = Article.objects.filter(id__in=[1,2,3])也可以通過(guò)其他的表的字段來(lái)判斷是否在某個(gè)集合中。示例代碼如下:
categories = Category.objects.filter(article__id__in=[1,2,3])如果要判斷相關(guān)聯(lián)的表的字段,那么也是通過(guò)
__來(lái)連接。并且在做關(guān)聯(lián)查詢的時(shí)候,不需要寫models_set,直接使用模型的名字的小寫化就可以了。比如通過(guò)分類去查找相應(yīng)的文章,那么通過(guò)article__id__in就可以了,而不是寫成article_set__id__in的形式。當(dāng)然如果你不想使用默認(rèn)的形式,可以在外鍵定義的時(shí)候傳遞related_query_name來(lái)指定反向查詢的名字。示例代碼如下:class Category(models.Model): name = models.CharField(max_length=100) class Meta: db_table = 'category' class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() cateogry = models.ForeignKey("Category",on_delete=models.CASCADE,null=True,related_query_name='articles') class Meta: db_table = 'article'因?yàn)樵?code>cateogry的
ForeignKey中指定了related_query_name為articles,因此你不能再使用article來(lái)進(jìn)行反向查詢了。這時(shí)候就需要通過(guò)articles__id__in來(lái)進(jìn)行反向查詢。
反向查詢是將模型名字小寫化。比如`article__in`。可以通過(guò)`related_query_name`來(lái)指定自己的方式,而不使用默認(rèn)的方式。
反向引用是將模型名字小寫化,然后再加上`_set`,比如`article_set`,可以通過(guò)`related_name`來(lái)指定自己的方式,而不是用默認(rèn)的方式。
并且,如果在做反向查詢的時(shí)候,如果查詢的字段就是模型的主鍵,那么可以省略掉這個(gè)字段,直接寫成`article__in`就可以了,不需要這個(gè)`id`了。
`in`不僅僅可以指定列表/元組,還可以為`QuerySet`。比如要查詢“文章標(biāo)題中包含有hello的所有分類”,那么可以通過(guò)以下代碼來(lái)實(shí)現(xiàn):
```python
articles = Article.objects.filter(title__icontains='hello')
categories = Category.objects.filter(articles__in=articles)
for cateogry in categories:
print(cateogry)
```
-
gt、gte、lt、lte:代表的是大于、大于等于、小于、小于等于的條件。示例代碼如下:
articles = Article.objects.filter(id__lte=3)
-
startswith、istartswith、endswith、iendswith:表示以某個(gè)值開(kāi)始,不區(qū)分大小寫的以某個(gè)值開(kāi)始、以某個(gè)值結(jié)束、不區(qū)分大小寫的以某個(gè)值結(jié)束。示例代碼如下:
articles = Article.objects.filter(title__endswith="hello")
-
關(guān)于時(shí)間的查詢條件:
-
range:可以指定一個(gè)時(shí)間段。并且時(shí)間應(yīng)該標(biāo)記為
aware時(shí)間,不然django會(huì)報(bào)警告。示例代碼如下:start_time = make_aware(datetime(year=2018,month=4,day=4,hour=17,minute=0,second=0)) end_time = make_aware(datetime(year=2018,month=4,day=4,hour=18,minute=0,second=0)) articles = Article.objects.filter(create_time__range=(start_time,end_time)) print(articles.query) print(articles)
-
* date:用年月日來(lái)進(jìn)行過(guò)濾。如果想要使用這個(gè)過(guò)濾條件,那么前提必須要在`MySQL`中添加好那些時(shí)區(qū)文件。如何添加呢?參考教案。示例代碼如下:
```python
articles = Article.objects.filter(create_time__date=datetime(year=2018,month=4,day=4))
```
* year/month/day:表示根據(jù)年/月/日進(jìn)行查找。示例代碼如下:
```python
articles = Article.objects.filter(create_time__year__gte=2018)
```
* week_day:根據(jù)星期來(lái)進(jìn)行查找。1表示星期天,7表示星期六,2-6代表的是星期一到星期五。比如要查找星期三的所有文章,那么可以通過(guò)以下代碼來(lái)實(shí)現(xiàn):
```python
articles = Article.objects.filter(create_time__week_day=4)
```
* time:根據(jù)分時(shí)秒來(lái)進(jìn)行查找。如果要具體到秒,一般比較難匹配到,可以使用區(qū)間的方式來(lái)進(jìn)行查找。區(qū)間使用`range`條件。比如想要獲取17時(shí)/10分/27-28秒之間的文章,那么可以通過(guò)以下代碼來(lái)實(shí)現(xiàn):
```python
start_time = time(hour=17,minute=10,second=27)
end_time = time(hour=17,minute=10,second=28)
articles = Article.objects.filter(create_time__time__range=(start_time,end_time))
```