annotate函数对于为表的每一行定义计算字段非常有用。模型属性也可用于定义计算字段,但是受限制(例如,不能用于排序)。
模型属性是否可以完全替换为带注释的字段?什么时候足以使用它们?
在某些情况下,注释肯定比属性更好,更容易。这些通常是在数据库中易于进行的计算,并且逻辑易于阅读。
另一方面,Django @property
是一种将计算逻辑写入模型的非常简单和Pythonic的方法。有些人认为它们是整洁的东西,有些人认为属性应该被烧掉并隐藏起来,因为它们将程序逻辑混合到数据对象中,这增加了复杂性。我认为特别是@cached_property
装饰器相当整洁。
但是,属性和注释不是查询和计算Django ORM中事物的唯一方法。
在许多复杂的情况下,属性或Model,Manager或QuerySet方法(尤其是custom QuerySets and Managers)在自定义查询时具有最大的灵活性。
大多数情况下,使用哪种方法速度无关紧要,并且应该使用最简洁,最简单的选项,最简单易读。尽量保持简单和愚蠢,你将拥有最少量的复杂代码来维护。
在某些情况下,当您遇到性能问题并最终分析SQL查询时,可能会被迫使用注释和自定义查询来优化您正在进行的查询的复杂性。当您在数据库中进行复杂查找并且不得不求助于计算任何属性中的内容或创建自定义SQL查询时,尤其如此。
如果你有大型查询集,计算属性中的东西可能会很复杂,因为你必须在Python中运行那些对象很大且迭代很慢的计算。另一方面,通过自定义SQL查询计算内容可能是一个需要维护的噩梦,特别是如果您维护的SQL不是由您编写的。
最后,它归结为速度要求和计算成本。如果使用普通Python进行计算不会降低服务速度或降低成本,那么您不应该优化。如果您正在为一组服务器付费,那么合理的优化可能会为您带来可以在其他地方使用的节省。使用10个小时优化一些片段可能不会真正收回成本,所以在这里要非常小心。
在优化案例中,如果您不是先知并且本能地知道问题是什么,那么您必须权衡不同的上下行并尝试不同的解决方案。如果问题很明显,那么它可能早先就已经过优化了,对吧?
在尝试不同的选项时,Django Debug Toolbar,SQL EXPLAIN和ANALYZE以及Python profiling都是你的朋友。
请记住,许多查询问题也是数据库相关的问题,您可能会因为糟糕的数据库设计或维护而损害您的性能。记得定期运行VACUUM并尝试normalize your database design。
Toolwise Django调试工具栏特别有用,因为它可以帮助进行性能分析和SQL分析。许多IDE(如PyCharm)也可以在正在运行的服务器上提供分析。如果您想要进行开发设置并将不同的工具集成到其中,这非常有用。