在Django模型中仅包含字段。

时间:2018-07-24 15:20:48

标签: django django-models

我有一个Django只读模型,它有一列包含geojson数据的字段,该字段很容易为500mb。

在大多数情况下,我不必使用此字段,因此我希望将其排除在标准选择查询之外。有什么办法可以排除它?我知道我可以使用values_list排除它,但是我对默认行为更感兴趣?

1 个答案:

答案 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} }。