Django能否懒加载模型中的字段?
我有一个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”这个字段。我个人觉得
only
比defer
更好,因为代码不仅更容易理解,而且在长期维护上也更方便。
20
这个功能是在你查询的时候使用 defer()
这个语句,而不是在模型定义的时候。你可以在这里查看相关文档:http://docs.djangoproject.com/en/dev/ref/models/querysets/#defer
其实,你提到的把数据重构到另一个表里的方案也是个很不错的选择。有些人可能会说,如果需要延迟加载字段,那就说明设计上有缺陷,数据应该以不同的方式建模。
不过,不管哪种方式都可以用!