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

发布于 2024-12-04 12:29:39 字数 594 浏览 0 评论 0原文

拥有模型:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃颗糖壮壮胆 2024-12-11 12:29:39

嗯,你正在比较苹果和橙子。它们的返回值可能几乎相同,但您在两者上做的事情不同。

我们先来看关系版本。该查询表示获取属于 nbook 的所有笔记。然后,您仅通过属于 nbook 的注释来过滤该查询集。实际上,您按照相同的标准对其进行了两次过滤。由于 Django 的查询集是惰性的,它实际上并没有做任何坏事,比如多次访问数据库,但这仍然是不必要的。

现在,第二个版本。在这里,您从所有笔记开始,然后筛选出属于特定笔记本的笔记。这次只有一个过滤器,但这样做不太好。既然它是一个关系,你应该通过关系格式来查找它,即nbook.note_set.all()。不过,在此版本中,您还使用了 select_lated(),而其他版本中并未使用该函数。

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

去掉这两个版本中的所有冗余,你只会得到:

notes = nbook.note_set.all()

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

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 to nbook. 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 using select_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 a Note. However, since the only relation on Note is Notebook and you already have the notebook, it's redundant.

Taking out all the redundancy in those two version leaves you with just:

notes = nbook.note_set.all()

That, too, will return exactly the same results as the other two version, but is much cleaner and standardized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文