prefetch_related和model_set在Django中的区别。

huangapple go评论106阅读模式
英文:

The difference between prefetch_related and model_set in Djnago

问题

我想知道在我需要检索外键模型对象时,最佳的流程是什么。

<br/>在views.py中使用**prefetch_related**是否是一个选择:
```python
queryset = queryset.prefetch_related('book_set')
context={objects:queryset}

或者直接在模板中使用model_set:

{% for attach in objects.book_set.all %}

哪个更好,哪一个对性能更好?


<details>
<summary>英文:</summary>

I wonder what is the best flow when I need to retrieve foreign key model objects.
========
 &lt;br/&gt;is it to use **prefetch_related** in views.py like:

queryset = queryset.prefetch_related('book_set')
context={objects:queryset}

or to use directly in the template by **model_set**:

{% for attach in objects.book_set.all %}

what is better and which one is good for performance?

</details>


# 答案1
**得分**: 1

在Django中,[prefetch_related][1]用于提前选择所有父对象的所有相关对象,主要与`ManyToMany`字段和反向关系一起使用。

而[model_set][2]用于获取单个父对象的所有相关对象,这将明显增加数据库的访问次数。

因此,最好使用`prefetch_related`,因为它将显著减少数据库的访问次数。

如果您不进行反向关系并且具有外键关系,那么首选使用[select_related][3]。

就在模板或视图中编写查询而言,我建议始终在视图中执行所有查询,因为模板会增加额外的开销。

[1]: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#prefetch-related
[2]: https://docs.djangoproject.com/en/4.0/topics/db/queries/#related-objects
[3]: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#select-related

<details>
<summary>英文:</summary>

In Django [prefetch_related][1] is used to select all related objects for all parent objects in advance mostly used with `ManyToMany` field and a reverse relationship. 

While as [model_set][2] is used to get all related objects of a single parent object which will definitely have more database hits.

Hence it is better to do `prefetch_related` as it will reduced the database hits significantly.

If you are not doing reverse relationship and have foreign key relation then [select_related][3] is prefered.

As far as writting queries in template or views is better. I would suggest always do all queries in the view as templates add extra level of overhead.


  [1]: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#prefetch-related
  [2]: https://docs.djangoproject.com/en/4.0/topics/db/queries/#related-objects
  [3]: https://docs.djangoproject.com/en/4.2/ref/models/querysets/#select-related

</details>



# 答案2
**得分**: 0

最佳方法取决于您的具体用例以及数据库的内容和大小。但一般来说,在``views.py``中使用`prefetch_related`可以通过减少数据库查询来提供更好的性能。

以下是一个示例,用于澄清这两种方法:

1. 在views.py中使用`prefetch_related()`:

```python
# views.py

queryset = Book.objects.all().prefetch_related('author')
context = {'books': queryset}
<!-- template.html -->

{% for book in books %}
    {{ book.title }} by {{ book.author.name }}
{% endfor %}

在这种方法中,prefetch_related('author')会在单个查询中获取所有相关的作者,从而减少了数据库查询次数。

  1. 在模板中使用model_set
<!-- template.html -->

{% for book in books %}
    {{ book.title }} by
    {% for author in book.author_set.all %}
        {{ author.name }}
    {% endfor %}
{% endfor %}

而在第二种方法中,每次迭代book.author_set.all都会访问数据库以检索相关的作者对象。这可能会导致多次数据库查询,并且可能会出现各种问题,特别是如果您有大量的书籍。

英文:

The best approach depends on your specific use case and the content and size of your database. However, generally using prefetch_related in the views.py can provide better performance by reducing database queries.

Here's an example to clarify both approaches:

  1. Using prefetch_related() in views.py:
# views.py

queryset = Book.objects.all().prefetch_related(&#39;author&#39;)
context = {&#39;books&#39;: queryset}
&lt;!-- template.html --&gt;

{% for book in books %}
    {{ book.title }} by {{ book.author.name }}
{% endfor %}

In this approach, the prefetch_related(&#39;author&#39;) fetches all related authors in a single query, reducing the number of database hits.

  1. Using model_set in the template:
&lt;!-- template.html --&gt;

{% for book in books %}
    {{ book.title }} by
    {% for author in book.author_set.all %}
        {{ author.name }}
    {% endfor %}
{% endfor %}

While on the second approach, each iteration of book.author_set.all hits the database to retrieve the related author object. This can result in multiple database queries, and different sort of problems, especially if you have a large number of books.

huangapple
  • 本文由 发表于 2023年8月10日 10:43:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76872345.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定