什么时候实际查询数据库并传输数据?

时间:2015-12-28 06:41:58

标签: python django django-models

我有这样的模特......

class Model():
    header = CharField()
    tagline = CharField()
    menubutton1 = Charfield()
    menubutton2 = CharField()

    page1 = CharField()
    page2 = CharField()

标题和标语进入每个模板,但page1和page2文本只会进入相应的页面。我做了一个查询,然后将它们包含在很多不同的视图中,所以我想知道是否所有数据都是从数据库中提取出来的,并且在进行查询时或在模板中调用数据时是否实际传输了这些数据?

1 个答案:

答案 0 :(得分:2)

QuerySets are lazy ( constructed, filtered, sliced, and generally passed around without actually hitting the database),但是一旦获取了模型,它就会从数据库中加载模型的所有字段。

defer()

但是,您可以在查询集上使用.defer()来排除在评估查询集时从数据库加载字段。它实际上是推迟加载这些字段。

  

在某些复杂的数据建模情况下,您的模型可能包含一个   很多字段,其中一些可能包含大量数据(例如,   文本字段),或需要昂贵的处理来转换它们   Python对象。如果您在某些情况下使用查询集的结果   您不知道是否需要这些特定字段的情况   当你最初获取数据时,你可以告诉Django不要检索   他们来自数据库。

所以,例如您希望作为第1页上下文的查询集排除字段page2

models_for_page_1 = Model.objects.defer('page2')

当评估上述查询集时,它将获取除page2

之外的所有字段
  

如果您访问,将从数据库中检索每个延迟字段   该字段(一次一个,而不是一次所有延迟字段)。

如果您不使用该字段的延迟加载从该查询集访问模型上的page2,则永远不会加载它,但如果您确实访问它,则会加载它单独访问时。

因此,只要第1页永远不会访问Model.page2,这就应该做你想要的。

only()

这是defer()补充,它只提取列出的字段,所以对你来说,例如:

models_for_page_1 = Model.objects.only('header', 'tagline', ..., 'page1')

defer() / only()values()

之间的差异

defer()only()返回模型实例,而values()返回值为

的字典