質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

723閲覧

Django クエリを最適化したい

nahi123

総合スコア14

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/04/17 02:59

Djangoで注文のサマリをリスト化して表示したいが、SQLのクエリが多いため、表示するための時間がかかる。
クエリを最適化する方法を知りたい。

class Company(models.Model): name = models.CharField(max_length=150) def get_order_count(self): orders = 0 for order in self.orders.all(): orders += 1 return orders def get_order_sum(self): total_sum = 0 for contact in self.contacts.all(): for order in contact.orders.all(): total_sum += order.total return total_sum class Contact(models.Model): company = models.ForeignKey( Company, related_name="contacts", on_delete=models.PROTECT) first_name = models.CharField(max_length=150) last_name = models.CharField(max_length=150, blank=True) def get_order_count(self): orders = 0 for order in self.orders.all(): orders += 1 return orders class Order(models.Model): order_number = models.CharField(max_length=150) company = models.ForeignKey(Company, related_name="orders") contact = models.ForeignKey(Contact, related_name="orders") total = models.DecimalField(max_digits=18, decimal_places=9) order_date = models.DateTimeField(null=True, blank=True) def __str__(self): return "%s" % self.order_number
class IndexView(ListView): template_name = "index.html" model = Company paginate_by = 50
<body> <div style="width:1020px; margin: 0 auto; border:1px solid blue;"> <table width="1020"> {% if is_paginated %} <tr><td> {% if page_obj.has_previous %} <a href="?page={{ page_obj.previous_page_number }}" class="pager-prev{% if not page_obj.has_previous %} inactive{% endif %}">&laquo;</a> {% endif %} </td> <td></td> <td></td> <td> {% if page_obj.has_next %} <a href="?page={{ page_obj.next_page_number }}" class="pager-next{% if not page_obj.has_next %} inactive{% endif %}">&raquo;</a> {% endif %} </td> </tr> {% endif %} <tr> <th>Name</th> <th>Order Count</th> <th>Order Sum</th> <th>Select</th> </tr> {% for company in company_list %} <tr> <td>{{ company.name }}</td> <td>{{ company.get_order_count }}</td> <td>{{ company.get_order_sum|floatformat:2 }}</td> <td><input type="checkbox" name="select{{company.pk}}" id=""></td> </tr> {% for contact in company.contacts.all %} <tr> <td>&nbsp;</td> <td>{{ contact.first_name }} {{ contact.last_name }}</td> <td>Orders: {{ contact.get_order_count }}</td> <td></td> </tr> {% endfor %} {% endfor %} </table> </div> </body>

期待する表示
|Name|Order Count|Order Sum|Select|
|:--|:--:|--:|
|CompanyA|8|2000|□
||PersonB|Orders: 2|
||PersonC|Orders: 5|
||PersonD|Orders: 1|
|CompanyB|9|1500|□
||PersonD|Orders: 3|
||PersonE|Orders: 1|
||PersonF|Orders: 5|
|CompanyC|15|3500|□
||PersonG|Orders: 10|
||PersonH|Orders: 2|
||PersonI|Orders: 3|

期待する表示通りにできてはいるが、SQL Queryが多すぎるため、表示までに時間がかかる。これを最適化して、高速化したい。
queryset = model.objects.annotateを使って、クエリを最適化し、htmlの記述を変えると良さそうだが、どう最適化したら良いかが分からない。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問