代码之家  ›  专栏  ›  技术社区  ›  nigel222

有没有办法知道相关对象是否已被预取?

  •  0
  • nigel222  · 技术社区  · 2 年前

    我想知道Django中是否有一种方法可以判断相关字段,特别是一对多关系中的“多”部分,是否是通过, prefetch_related() 却没有真正拿到?

    因此,举个例子,假设我有以下模型:

    class Question(Model):
      """Class that represents a question."""
    
    class Answer(Model):
      """Class the represents an answer to a question."""
      question = ForeignKey('Question', related_name='answers')
    

    通常,要获得一个问题的答案数量,最有效的方法是执行以下操作(因为Django文档指出 count() 如果您只需要计数,则效率更高):

    # Note: "question" is an instance of class Question.
    answer_count = question.answers.count()
    

    然而,在某些情况下,答案可能是通过 prefetch_related() call(或者以某种方式,比如之前已经遍历了答案)。因此,在这种情况下,这样做会更有效(因为我们会跳过额外的计数查询):

    # Answers were fetched via prefetch_related()
    answer_count = len(question.answers.all())
    

    所以我真正想做的是:

    if question.answers_have_been_prefetched:  # Does this exist?
      answer_count = len(question.answers.all())
    else:
      answer_count = question.answers.count()
    

    如果重要的话,我会使用Django 1.4。提前谢谢。

    编辑:添加了澄清 prefetch_related() 并不是唯一能找到答案的方法。

    0 回复  |  直到 11 年前
        1
  •  41
  •   Kevin Stone    11 年前

    是的,Django将预取的结果存储在 _prefetched_objects_cache 父模型实例的属性。

    所以你可以这样做:

    instance = Parent.objects.prefetch_related('children').all()[0]
    
    try:
        instance._prefetched_objects_cache[instance.children.prefetch_cache_name]
        # Ok, it's pefetched
        child_count = len(instance.children.all())
    except (AttributeError, KeyError):
        # Not prefetched
        child_count = instance.children.count()
    

    请参阅 relevant use 在django源中继或 the equivalent v1.4.9中