在Django中过滤对象的最实用有效的方法是什么?

时间:2017-11-08 02:25:37

标签: python django filtering django-queryset

Django中过滤对象的最佳方法是什么?

就我而言,我需要按GET request发送的不同参数来过滤对象。因此,在我的get_queryset CBV中,我将值发送到自定义models.QuerySet的自定义函数并检索结果:

return MyModel.objects.all().custom_filter(param1, param2, param3)

但在我的自定义功能中,最令人怀疑的事情正在发生。

  1. 首先,我检查存在的值并清除它们。
  2. 然后,为每个参数分别使用Q Objects过滤查询集。在自定义models.QuerySet中,它看起来像:

    def custom_filter(self, param1, param2, param3):
        # cleaning and checking staff
        # ... then
        result = self.filter(Q() | Q()) # related to param1
        if (param2 != None):
            result = result.filter(Q()) # related to param2
        if (param3 != None):
            result = result.filter(Q() & Q()) # related to param3
        # and etc.
        return result.distinct()
    
  3. 这个时候工作正常。但我认为这绝对是效率低下。如果有人有更好的解决方案,请提供。

1 个答案:

答案 0 :(得分:1)

不要想 - 衡量。查询需要多长时间?您可以在部署之前在生产方式区域中测试它吗?

您可以通过查看任何查询集上的.query来查看发送到数据库的查询。通过以这种方式查看真实查询,您可以更好地了解您的查询是否可怕。

print unicode(MyModel.objects.all().custom_filter(param1, param2, param3).query)

如果您想要更高级的细分,通常我会将这些细分并将其弹出到数据库中的EXPLAIN ANALYSE。这将为您提供有关您的数据库用于实际收集结果的魔力的完整细分。您需要查找数据库文档以获取有关此方法的更多信息,因为它会有所不同。

最后 - 但也许最重要的是 - querysets only evaluate when they have to。在您提供的示例中,根本不会进行任何数据库查询。你认为它绝对是低效的 - 但我看不出你为什么会这么想的原因。