我有一个Django只读模型,它有一列包含geojson数据的字段,该字段很容易为500mb。
在大多数情况下,我不必使用此字段,因此我希望将其排除在标准选择查询之外。有什么办法可以排除它?我知道我可以使用values_list
排除它,但是我对默认行为更感兴趣?
答案 0 :(得分:3)
您可以使用.defer('field1', 'field2')
[Django-doc]来防止Django立即 获取某些字段。在这种情况下,以后可以通过额外的查询来获取它们。
因此您可以将查询编写为:
SomeModel.objects.all().defer('geo_field')
将其从提取中排除。然后查询集包含SomeModel
对象,因此不包含值列表。可以使用您在SomeModel
上定义的行为(例如,实用程序方法)。此外,您仍然可以 使用some_model_object.geo_field
,但是在访问相应的值之前,将需要额外的提取。
但是建议仅使用 这样的技巧,以防某些列的处理非常重要。毕竟,此类额外的查询也需要时间。如果您经常需要这种字段,通常只会导致处理成本更高。
Manager
上面的内容当然不是很优雅:现在我们必须为每个查询编写.defer(..)
。但是,我们可以设计一个在访问SomeModel.objects
时自动延迟的管理器:
from django.db import models
class GeoManager(models.Manager):
def get_queryset(self):
return super().get_queryset().defer('geo_field')
然后在SomeModel
中,我们可以将此管理器用于objects
,而不是默认的管理器:
class SomeModel(models.Model):
geo_field = ...
objects = GeoManager()
with_geofield = models.Manager()
因此,如果您访问geo_field
,则默认情况下,您将不在此处获取SomeModel.objects
,并且如果您知道自己需要它,则可以使用SomeModel.with_geofield
立即获取{{1} }。