1. 程式人生 > 實用技巧 >orm之F查詢Q查詢

orm之F查詢Q查詢

ORM之F查詢和Q查詢

F查詢和Q查詢

\1. 當需要欄位和欄位作比較的時候用F查詢

\2. 當查詢條件是 或 的時候 用Q查詢,因為預設的filter引數都是且的關係

F查詢

在之前的所有的例子中,我們構造的過濾器都只是將欄位值與某個常量做比較。如果我們要對兩個欄位的值做比較,那該怎麼做呢?

Django 提供 F() 來做這樣的比較。F() 的例項可以在查詢中引用欄位,來比較同一個 model 例項中兩個不同欄位的值。

示例1:

查詢評論數大於收藏數的書籍

from django.db.models import F
models.Book.objects.filter(commnet_num__gt=F('keep_num'))

Django 支援 F() 物件之間以及 F() 物件和常數之間的加減乘除和取模的操作。

models.Book.objects.filter(commnet_num__lt=F('keep_num')*2)

修改操作也可以使用F函式,比如將每一本書的價格提高30元

models.Book.objects.all().update(price=F("price")+30)

引申

如果要修改char欄位咋辦?

如:把所有書名後面加上(第一版)

>>> from django.db.models.functions import Concat
>>> from django.db.models import Value
>>> models.Book.objects.all().update(title=Concat(F("title"), Value("("), Value("第一版"), Value(")")))
# SQL分析:
models.Book.objects.all().update(title)   #  更新title欄位
title=Concat(F("title"), Value("("), Value("第一版"), Value(")")) 
# 1.Concat把字串F('title') 和 Value(表示轉換成值)'第一版' 拼接起來

Q查詢

filter() 等方法中的關鍵字引數查詢都是一起進行“AND” 的。 如果你需要執行更復雜的查詢(例如OR語句),你可以使用Q物件。

示例1:

查詢作者名是小仙女或小魔女的

models.Book.objects.filter(Q(authors__name="小仙女")|Q(authors__name="小魔女"))

你可以組合&| 操作符以及使用括號進行分組來編寫任意複雜的Q 物件。同時,Q 物件可以使用~ 操作符取反,這允許組合正常的查詢和取反(NOT) 查詢。

示例:查詢作者名字是小仙女並且不是2018年出版的書的書名。

>>> models.Book.objects.filter(Q(author__name="小仙女") & ~Q(publish_date__year=2018)).values_list("title")
<QuerySet [('番茄物語',)]>

查詢函式可以混合使用Q 物件和關鍵字引數。所有提供給查詢函式的引數(關鍵字引數或Q 物件)都將"AND”在一起。但是,如果出現Q 物件,它必須位於所有關鍵字引數的前面。

例如:查詢出版年份是2017或2018,書名中帶物語的所有書。

>>> models.Book.objects.filter(Q(publish_date__year=2018) | Q(publish_date__year=2017), title__icontains="物語")
<QuerySet [<Book: 番茄物語>, <Book: 香蕉物語>, <Book: 橘子物語>]>

Q查詢輸入字串

Book.objects.filter(Q(title="linux") | Q(price=123))

上面的方式查詢條件只能是欄位名。

如果我們只有字串怎麼寫呢? “title” “price”

q = Q()                                # 例項化一個Q物件
q.connector = "or"                     # 預設是且的關係
q.children.append("title", "linux")    
q.children.append("price", 123)
Book.objects.filter(q)                 # 這個效果和上面的一樣,只是條件可以是字串了