Django 视图 - 外键模型中的最佳查询集
拥有模型:
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)
Having the model:
class Notebook(models.Model):
n_id = models.AutoField(primary_key = True)
class Note(models.Model):
b_nbook = models.ForeignKey(Notebook)
the URL pattern passing one parameter:
(r'^(?P<n_id>\d+)/
and the following view:
def notebook_notes(request, n_id):
nbook = get_object_or_404(Nbook, pk=n_id)
...
which of the following is the optimum query set, and why? (they both work and pass the notes based to a selected by URL notebook)
notes = nbook.note_set.filter(b_nbook = n_id)
notes = Note.objects.select_related().filter(b_nbook = n_id)
, 'notebook_notes')
and the following view:
which of the following is the optimum query set, and why? (they both work and pass the notes based to a selected by URL notebook)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,你正在比较苹果和橙子。它们的返回值可能几乎相同,但您在两者上做的事情不同。
我们先来看关系版本。该查询表示获取属于
nbook
的所有笔记。然后,您仅通过属于nbook
的注释来过滤该查询集。实际上,您按照相同的标准对其进行了两次过滤。由于 Django 的查询集是惰性的,它实际上并没有做任何坏事,比如多次访问数据库,但这仍然是不必要的。现在,第二个版本。在这里,您从所有笔记开始,然后筛选出属于特定笔记本的笔记。这次只有一个过滤器,但这样做不太好。既然它是一个关系,你应该通过关系格式来查找它,即
nbook.note_set.all()
。不过,在此版本中,您还使用了select_lated()
,而其他版本中并未使用该函数。select_lated
将尝试与模型上的任何其他关系(在本例中为Note
)创建连接表。但是,由于Note
上的唯一关系是Notebook
并且您已经拥有笔记本,因此它是多余的。去掉这两个版本中的所有冗余,你只会得到:
这也将返回与其他两个版本完全相同的结果,但更加干净和标准化。
Well you're comparing apples and oranges a bit there. They may return virtually the same, but you're doing different things on both.
Let's take the relational version first. That query is saying get all the notes that belong to
nbook
. You're then filtering that queryset by only notes that belong tonbook
. You're filtering it twice on the same criteria, in effect. Since Django's querysets are lazy, it doesn't really do anything bad, like hit the database multiple times, but it's still unnecessary.Now, the second version. Here, you're starting with all notes and filtering to just those that belong to the particular notebook. There's only one filter this time, but it's bad form to do it this way. Since it's a relation, you should look it up through the relational format, i.e.
nbook.note_set.all()
. On this version, though, you're also usingselect_related()
, which wasn't used on the other version.select_related
will attempt to create a join table with any other relations on the model, in this case aNote
. However, since the only relation onNote
isNotebook
and you already have the notebook, it's redundant.Taking out all the redundancy in those two version leaves you with just:
That, too, will return exactly the same results as the other two version, but is much cleaner and standardized.