2011-04-16 65 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)