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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

1回答

635閲覧

viewsでfor文を回し、テンプレート側に渡したい。

yoshiringoo

総合スコア4

Django

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2023/03/04 07:45

編集2023/03/05 17:17

実現したいこと

viewsでfor文を回し、テンプレート側に渡したい。

前提

ゴルフのスコアアプリを作っていて、各プレイヤー(Personモデル)毎にスコア(Statモデルのtotal_score)を登録できます(スコアはプレイヤー一人毎に何件でも登録できます)。
男女別などで平均スコアを出したい(男平均:98とか)のですが、そこで詰まっています。
Personモデル(名前や性別を登録できる)とStatモデル(スコアなどを登録できる)があります。
views.pyで男Playerのidをリストで取得することは出来ており、そのidをfor文で回して平均を出そうとしています。
for文を使用しなければいけないわけではないので、その他の方法で男女別平均スコアを出す方法があればそれでも教えていただけると幸いです。

発生している問題・エラーメッセージ

現在の状態ですと、for文で回したいリストの最後の値だけしかテンプレート側に渡せていないです。

該当のソースコード

views.py

1class Average(generic.ListView): 2 model = Stat 3 template_name = "score/average.html" 4 5 def get_context_data(self, **kwargs): 6 context = super().get_context_data(**kwargs) 7 8 #男性プレイヤーのidを取得。男性プレイヤーidが4と8の二人なので<QuerySet [4, 8]>と表示されます。 9 males_id = Person.objects.filter(sex="男性").values_list("id", flat=True) 10 11   #上手くいかない箇所です。males_idをfor文で回そうとしていますが、id=8の結果しかテンプレートに渡せていません。 12 for males_pk in males_id: 13 males_avg = Stat.objects.filter(player=males_pk).aggregate(Avg('total_score')) 14 context["males_avg"] = males_avg 15 16 context["males_id"] = males_id 17 18 return context

models.py

1 2class Person(models.Model): 3 sex = models.CharField(verbose_name="性別", choices=settings.SEX, max_length=2) 4 5class Stat(models.Model): 6 player = models.ForeignKey(to=Person, verbose_name='プレイヤー', on_delete=models.CASCADE) 7 total_score = models.PositiveSmallIntegerField(verbose_name='スコア', blank=False, null=False) 8 9 def __str__(self): 10 return f'#{self.pk} {self.player}'

試したこと

males_avg = Stat.objects.filter(player__sex=males_pk).aggregate(Avg('total_score'))
としてみましたが、これだとPerson毎に平均を出せていないため、total_scoreのデータ数が多いPersonに結果が偏ってしまいダメでした。

クエリセットではなくリストで出すために
males_id = list(males_id)としてみましたが結果は変わりませんでした。

補足情報(FW/ツールのバージョンなど)

django=3.2.1
python=3.9.5

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

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

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

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

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

guest

回答1

0

自己解決

pandasのgroupbyを使用したところ解決いたしました。
#views.py

def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) df = pd.DataFrame(Stat.objects.filter(player__sex="男性").values()) male_avgs = df[["player_id","total_score"]].groupby("player_id").agg("mean")["total_score"].mean() context["male_avgs"] = male_avgs return context

投稿2023/03/06 14:29

yoshiringoo

総合スコア4

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問