2011-04-16 67 views
27

我有一個內置於我的Django模型類的函數,我想使用該函數來過濾我的查詢結果。Django:基於自定義函數的過濾器查詢

class service: 
     ...... 
     def is_active(self): 
      if datetime.now() > self.end_time: 
        return False 
      return True 

現在我想要使用此功能爲我的查詢過濾器,像

nserv = service.objects.filter(is_active=True) 

我知道,對於這個簡單的「IS_ACTIVE」的情況下,我可以直接使這種對比中篩選查詢,但對於更復雜的情況,這可能是不可能的。我應該如何根據自定義函數進行查詢?

+3

順便說一句,你可以做'返回datetime.now()<= self.end_time' :-) – Rikki 2014-10-29 23:15:17

+0

我有完全相同的問題!即使功能被稱爲相同 – 2018-03-04 19:24:52

回答

17

我會建議你使用自定義的經理你的類,這樣你可以使用:

nserv = service.objects.are_active()

這東西可實現如:

class ServiceManager(models.Manager): 
    def are_active(self): 
     # use your method to filter results 
     return you_custom_queryset 

請參閱custom managers

+20

'#使用您的方法來過濾結果'幾乎是問題所在,要求如何做。 – 2011-04-16 07:52:55

+0

@Ignacio - 其實這個解決方案也適合我。所以我會爲了嘗試一些不同的東西而去。 – Neo 2011-04-16 10:46:34

16

您可能無法做到,而是可以使用list comprehensiongenerator expression對查詢集進行後處理。

例如:

[x for x in Q if x.somecond()] 
+3

什麼是LC/genex? – Neo 2011-04-16 07:09:55

+6

LC = [list comprehension](http://docs.python.org/tutorial/datastructures.html#list-comprehensions)。 genex = [生成器表達式](http://docs.python.org/reference/expressions.html#generator-expressions) – 2011-04-16 07:32:07

+0

@李 - :P我還沒有趕上Python的行話速度。 – Neo 2011-04-16 08:24:47

13

我剛剛有類似的問題。問題是我不得不返回一個QuerySet實例。我快速的解決辦法是做這樣的事情:

active_serv_ids = [service.id for service in Service.objects.all() if service.is_active()] 
nserv = Service.objects.filter(id__in=active_serv_ids) 

很肯定這是不是這樣做的最漂亮的和高性能的方式,但我對我的作品。

這樣做更詳細的辦法是:

active_serv_ids = [] 

for service in Service.objects.all(): 
if service.is_active(): 
    active_serv_ids.append(service.id) 

nserv = Service.objects.filter(id__in=active_serv_ids) 
+0

謝謝,這是完美的。它不是django「加載結果」並進行客戶端過濾的功能,所以這是唯一的方法。 – beiller 2016-10-25 15:00:24

4

由伊格納西奧答案很有趣,但它不返回的查詢集。這一個作用:

def users_by_role(role): 
    users = User.objects.all() 
    ids = [user.id for user in users if user.role == role] 
    return users.filter(id__in=ids)