拥有模型:
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)
答案 0 :(得分:1)
嗯,你在那里比较苹果和橘子。它们可能几乎相同,但你在两者上都做了不同的事情。
让我们首先考虑关系版本。该查询说的是获取属于nbook
的所有笔记。然后,您只能通过属于nbook
的便笺过滤该查询集。你实际上是按照相同的标准过滤了两次。由于Django的查询集是懒惰的,它并没有真正做任何坏事,比如多次点击数据库,但它仍然是不必要的。
现在,第二个版本。在这里,您将从所有笔记开始,并过滤到属于特定笔记本的那些笔记。这次只有一个过滤器,但这样做是不好的形式。由于它是一种关系,你应该通过关系格式查找它,即nbook.note_set.all()
。但是,在此版本中,您还使用了select_related()
,而其他版本未使用该版本。
select_related
将尝试使用模型上的任何其他关系创建连接表,在本例中为Note
。但是,由于Note
上的唯一关系是Notebook
并且您已经拥有笔记本,因此它是多余的。
取出这两个版本中的所有冗余,只剩下:
notes = nbook.note_set.all()
这也将返回与其他两个版本完全相同的结果,但更清洁和标准化。