django中的F和Q
阿新 • • 發佈:2019-02-02
價格 span UNC 條件 not 字符串 upd func opera
F查詢
Django 提供 F() 來做這樣的比較。F() 的實例可以在查詢中引用字段,來比較同一個 model 實例中兩個不同字段的值。
查詢書id大於\小於價格的書籍
1 models.Book.objects.filter(id__gt=F("price")) 2 <QuerySet []> 3 4 models.Book.objects.filter(id__lt=F("price")) 5 <QuerySet [<Book: 書一>, <Book: 書二>, <Book: 書三>, <Book: 書四>, <Book: 書五>, <Book: 書六>]>
Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操作。
1 models.Book.objects.filter(id__lt=F("price")/2) 2 <QuerySet [<Book: 書一>, <Book: 書二>, <Book: 書三>, <Book: 書四>, <Book: 書五>]>
修改操作也可以使用F函數,比如將每一本書的價格提高30元
models.Book.objects.all().update(price=F("price")+30)
字符串使用Concat連接
from django.db.models.functions import Concat from django.db.models import Value models.Book.objects.update(title=Concat(F("title"),Value("("),Value("第"),Value(")")))
Q查詢主要是用來做and, or, not 查詢的
AND查詢
將多個 Q 對象作為非關鍵參數或使用 & 聯結即可實現 AND 查詢:
>>> from django.db.models importQ # Q(...) >>> Question.objects.filter(Q(question_text__contains=‘you‘)) [<Question: what are you doing>, <Question: what is wrong with you>, <Question: who are you>] # Q(...), Q(...) >>> Question.objects.filter(Q(question_text__contains=‘you‘), Q(question_text__contains=‘what‘)) [<Question: what are you doing>, <Question: what is wrong with you>] # Q(...) & Q(...) >>> Question.objects.filter(Q(question_text__contains=‘you‘) & Q(question_text__contains=‘what‘)) [<Question: what are you doing>, <Question: what is wrong with you>]
OR查詢
使用 | 聯結兩個 Q 對象即可實現 OR 查詢:
# Q(...) | Q(...) >>> Question.objects.filter(Q(question_text__contains=‘you‘) | Q(question_text__contains=‘who‘)) [<Question: what are you doing>, <Question: what is wrong with you>, <Question: who are you>, <Question: who am i>]
NOT查詢
使用 ~Q(...) 客戶實現 NOT 查詢:
# ~Q(...) >>> Question.objects.filter(~Q(question_text__contains=‘you‘)) [<Question: who am i>]
與關鍵字參數共用
記得要把 Q 對象放前面:
# Q(...), key=value >>> Question.objects.filter(Q(question_text__contains=‘you‘), question_text__contains=‘who‘) [<Question: who are you>]
動態構建查詢條件
比如你定義了一個包含一些 Q 對象的列表,如何使用這個列表構建 AND 或 OR 查詢呢? 可以使用 operator 和 reduce:
>>> lst = [Q(question_text__contains=‘you‘), Q(question_text__contains=‘who‘)] # OR >>> Question.objects.filter(reduce(operator.or_, lst)) [<Question: what are you doing>, <Question: what is wrong with you>, <Question: who are you>, <Question: who am i>] # AND >>> Question.objects.filter(reduce(operator.and_, lst)) [<Question: who are you>]
這個列表也可能是根據用戶的輸入來構建的,比如簡單的搜索功能(搜索一個文章的標題或內容或作者名稱包含某個關鍵字):
q = request.GET.get(‘q‘, ‘‘).strip() lst = [] if q: for key in [‘title__contains‘, ‘content__contains‘, ‘author__name__contains‘]: q_obj = Q(**{key: q}) lst.append(q_obj) queryset = Entry.objects.filter(reduce(operator.or_, lst))
django中的F和Q