【Python】在Django中使用Q()物件

小亮520cl發表於2018-01-19

轉載於:  

 

問題

一般我們在Django程式中查詢資料庫操作都是在QuerySet裡進行進行,例如下面程式碼:

>>> q1 = Entry.objects.filter(headline__startswith="What") >>> q2 = q1.exclude(pub_date__gte=datetime.date.today()) >>> q3 = q1.filter(pub_date__gte=datetime.date.today())
  

或者將其組合起來,例如:

>>>q1 = Entry.objects.filter(headline_startswith="What").exclude(pub_date_gte=datetime.date.today())
 

隨著我們的程式越來越複雜,查詢的條件也跟著複雜起來,這樣簡單的透過一個filter()來進行查詢的條件將導致我們的查詢越來越長。

 

 

Q()物件就是為了將這些條件組合起來。

當我們在查詢的條件中需要組合條件時(例如兩個條件“且”或者“或”)時。我們可以使用Q()查詢物件。例如下面的程式碼

fromdjango.db.modelsimports Q
q=Q(question_startswith="What")
 

這樣就生成了一個Q()物件,我們可以使用符號&或者|將多個Q()物件組合起來傳遞給filter(),exclude(),get()等函式當多個Q()物件組合起來時,Django會自動生成一個新的Q()。例如下面程式碼就將兩個條件組合成了一個

Q(question__startswith='Who') | Q(question__startswith='What')
 

使用上述程式碼可以使用SQL語句這麼理解:

WHEREquestionLIKE 'Who%' ORquestionLIKE 'What%'
 

我們可以在Q()物件的前面使用字元“~”來代表意義“非”,例如下面程式碼:

Q(question__startswith='Who') | ~Q(pub_date__year=2005)
 

對應SQL語句可以理解為:

WHEREquestionlike "Who%" ORyear(pub_date) !=2005
  

這樣我們可以使用 “&”或者“|”還有括號來對條件進行分組從而組合成更加複雜的查詢邏輯。

也可以傳遞多個Q()物件給查詢函式,例如下面程式碼:

News.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)
  

多個Q()物件之間的關係Django會自動理解成“且(and)”關係。如上面程式碼使用SQL語句理解將會是:

SELECT * fromnewsWHEREquestionLIKE 'Who%'  AND (pub_date = '2005-05-02' ORpub_date = '2005-05-06')
  

Q()物件可以結合關鍵字引數一起傳遞給查詢函式,不過需要注意的是要將Q()物件放在關鍵字引數的前面,看下面程式碼

#正確的做法
News.objects.get(
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
    question__startswith='Who')
  #錯誤的做法,程式碼將關鍵字引數放在了Q()物件的前面。
News.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29096438/viewspace-2150333/,如需轉載,請註明出處,否則將追究法律責任。

相關文章