【问题标题】:django - when is .objects.get() evaluated?django - .objects.get() 何时评估?
【发布时间】:2012-11-16 23:31:50
【问题描述】:

假设我有:

class Library(models.Model):
    name = models.CharField(max_length = 100)

class Books(models.Model):
    library = models.ForeignKey(Library)
    book = models.CharField(max_length = 100)

我想创建一个新的Books,我们知道我们可以只用Library 的ID 填充Books 上的库,但我们也可以使用Library 的实例。我的问题是,如果我们只提供 id 会更好吗?如果我想使用实例,那么我必须使用.get() 进行评估,然后它会命中数据库吗?

附加问题:从文档来看,queryset 是惰性的,它在评估之前不会访问数据库,那么 queryset 什么时候评估?

【问题讨论】:

    标签: python django


    【解决方案1】:

    是的,.get() 会立即被评估。当然,使用 ID 可以避免数据库查询。

    get 并不懒惰,因为它不返回 QuerySet - 它返回模型的单个实例。 QuerySets 来自 .filter() 之类的东西,因此例如 Library.objects.filter(id=5) 被延迟评估,而 Library.objects.get(id=5) 被立即评估。

    查询集的实际评估包含在docs 中 - 基本上,任何时候您实际从查询集中提取一个值,它都会被评估。完整列表如下:

    • 迭代
    • 切片
    • 酸洗
    • repr()
    • len()
    • list()
    • bool()

    【讨论】:

    • 请注意,对未计算的 QuerySet 进行切片通常会返回另一个未计算的 QuerySet。
    • 我相信 get 也是懒惰的评估。在访问变量 docs.djangoproject.com/en/dev/topics/db/optimization/… 之前,您不会访问数据库
    • @ppetrid 那是在谈论相关变量的查找。如果您安装了 django 调试工具栏,很容易通过在 debugsqlshell 中调用它来验证 get 是否立即被评估 - 您将看到立即构建和执行的查询。
    • 感谢您澄清这一点,不知何故,我一直认为它像查询集一样工作..
    • 使用.filter()而不是.get()然后调用.first()如果/当你真的需要数据来强制延迟评估时会是不好的做法吗?
    猜你喜欢
    • 2023-04-05
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    相关资源
    最近更新 更多