Django视图 - ForeignKey模型中的最佳查询集

时间:2011-09-15 14:52:46

标签: django django-views

拥有模型:

class Notebook(models.Model):
    n_id = models.AutoField(primary_key = True)

class Note(models.Model):
    b_nbook = models.ForeignKey(Notebook)

传递一个参数的URL模式:

(r'^(?P<n_id>\d+)/$', 'notebook_notes')

和以下观点:

def notebook_notes(request, n_id):
    nbook = get_object_or_404(Nbook, pk=n_id)
...

以下哪一项是最佳查询集,为什么? (他们都工作并根据URL笔记本选择传递笔记)

notes = nbook.note_set.filter(b_nbook = n_id)
notes = Note.objects.select_related().filter(b_nbook = n_id)

1 个答案:

答案 0 :(得分:1)

嗯,你在那里比较苹果和橘子。它们可能几乎相同,但你在两者上都做了不同的事情。

让我们首先考虑关系版本。该查询说的是获取属于nbook的所有笔记。然后,您只能通过属于nbook的便笺过滤该查询集。你实际上是按照相同的标准过滤了两次。由于Django的查询集是懒惰的,它并没有真正做任何坏事,比如多次点击数据库,但它仍然是不必要的。

现在,第二个版本。在这里,您将从所有笔记开始,并过滤到属于特定笔记本的那些笔记。这次只有一个过滤器,但这样做是不好的形式。由于它是一种关系,你应该通过关系格式查找它,即nbook.note_set.all()。但是,在此版本中,您还使用了select_related(),而其他版本未使用该版本。

select_related将尝试使用模型上的任何其他关系创建连接表,在本例中为Note。但是,由于Note上的唯一关系是Notebook并且您已经拥有笔记本,因此它是多余的。

取出这两个版本中的所有冗余,只剩下:

notes = nbook.note_set.all()

这也将返回与其他两个版本完全相同的结果,但更清洁和标准化。