Django能否懒加载模型中的字段?

23 投票
3 回答
26460 浏览
提问于 2025-04-16 00:05

我有一个django模型里面有一个很大的 TextField 字段,但我经常用不到这个字段。有没有办法让django“懒加载”这个字段?也就是说,只有在我明确需要的时候才从数据库里取这个字段的数据。每次我提到这些对象的时候,都会把这个 TextField 的内容拉到python里,这样浪费了很多内存和带宽。

另外一个办法是为这个字段的内容创建一个新表,但如果可以的话,我更想避免这种复杂的做法。

3 个回答

7

对于这种情况,你可以直接覆盖默认的管理器。通常来说,这样做并不推荐,但对于defer()来说,这样做是有道理的:

    class CustomManager(models.Manager):
        def get_queryset(self):
            return super(CustomManager, self).get_queryset().defer('YOUR_TEXTFIELD_FIELDNAME')

    class DjangoModel(models.Model):
        objects = CustomerManager()
9

在Django中,有两种懒加载的方式:

  • defer(*fields)

    这个方法会跳过那些需要复杂处理才能转换成Python对象的字段,避免不必要的开销。

    比如,你可以这样写:Entry.objects.defer("text"),这样就不会加载“text”这个字段。

  • only(*fields)

    这个方法只加载你真正需要的字段。

    例如,你可以这样写:Person.objects.only("name"),这样只会加载“name”这个字段。

    我个人觉得onlydefer更好,因为代码不仅更容易理解,而且在长期维护上也更方便。

20

这个功能是在你查询的时候使用 defer() 这个语句,而不是在模型定义的时候。你可以在这里查看相关文档:http://docs.djangoproject.com/en/dev/ref/models/querysets/#defer

其实,你提到的把数据重构到另一个表里的方案也是个很不错的选择。有些人可能会说,如果需要延迟加载字段,那就说明设计上有缺陷,数据应该以不同的方式建模。

不过,不管哪种方式都可以用!

撰写回答