在Django
中过滤对象的最佳方法是什么?
就我而言,我需要按GET request
发送的不同参数来过滤对象。因此,在我的get_queryset
CBV
中,我将值发送到自定义models.QuerySet
的自定义函数并检索结果:
return MyModel.objects.all().custom_filter(param1, param2, param3)
但在我的自定义功能中,最令人怀疑的事情正在发生。
然后,为每个参数分别使用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()
这个时候工作正常。但我认为这绝对是效率低下。如果有人有更好的解决方案,请提供。
答案 0 :(得分:1)
不要想 - 衡量。查询需要多长时间?您可以在部署之前在生产方式区域中测试它吗?
您可以通过查看任何查询集上的.query
来查看发送到数据库的查询。通过以这种方式查看真实查询,您可以更好地了解您的查询是否可怕。
print unicode(MyModel.objects.all().custom_filter(param1, param2, param3).query)
如果您想要更高级的细分,通常我会将这些细分并将其弹出到数据库中的EXPLAIN ANALYSE
。这将为您提供有关您的数据库用于实际收集结果的魔力的完整细分。您需要查找数据库文档以获取有关此方法的更多信息,因为它会有所不同。
最后 - 但也许最重要的是 - querysets only evaluate when they have to。在您提供的示例中,根本不会进行任何数据库查询。你认为它绝对是低效的 - 但我看不出你为什么会这么想的原因。