Django:根据自定义函数过滤查询

Posted

技术标签:

【中文标题】Django:根据自定义函数过滤查询【英文标题】:Django : Filter query based on custom function 【发布时间】:2011-08-06 19:14:57 【问题描述】:

我的 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' 情况,我可以直接在过滤器查询中进行这种比较,但对于更复杂的情况,这可能是不可能的。如何根据自定义函数进行查询?

【问题讨论】:

顺便说一句,你可以做return datetime.now() <= self.end_time :-) 我遇到了完全相同的问题!甚至函数也被称为相同 这里提出的答案首先进行查询,然后过滤。对于庞大的数据集和限制性过滤,将函数的输出存储在模型的字段中以便直接对数据库查询进行过滤而不是事后进行过滤会更有效。 【参考方案1】:

我刚刚遇到了类似的问题。问题是我必须返回一个 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)

【讨论】:

谢谢你这是完美的。 “加载结果”并进行客户端过滤还不是 django 的功能,所以这是唯一的方法。 它不是最佳的,因为它会执行查询并且只使用其中的一部分,但如果您确定您的过滤器将保留大部分结果,这是一个很好的解决方法 它就像一个魅力。尝试在循环之前尽可能多地过滤 django【参考方案2】:

我建议您为您的班级使用自定义管理器,您可以像这样使用:

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

【讨论】:

# use your method to filter results 几乎就是问题所在。 @Ignacio - 实际上这个解决方案也适合我。所以我会选择它,只是为了尝试不同的东西。【参考方案3】:

您可能无法这样做,而是可以使用 list comprehension 或 generator expression 对查询集进行后处理。

例如:

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

【讨论】:

LC = list comprehension。基因 = generator expression @A lee - :P 我还没有掌握 Python 术语。 @Neo 没关系,我以前从未听说过人们将它们称为 LC 或genex。 这不返回查询集,因此不能在某些情况下使用(例如,填充表单中的选择框)【参考方案4】:

Ignacio 的回答很有趣,但它没有返回查询集。这个可以:

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)

【讨论】:

以上是关于Django:根据自定义函数过滤查询的主要内容,如果未能解决你的问题,请参考以下文章

url查询中的Django自定义排序

Django自定义查询对象

Django自定义过滤器

Django—— 模板层:变量过滤器标签自定义标签和过滤器

django 第五课自定义模板过滤器与标签

在已过滤的查询集上使用 Django 自定义管理器功能