質問編集履歴

1

質問内容が分かりにくかったため、編集しました

2019/01/28 11:58

投稿

shohei0718
shohei0718

スコア17

test CHANGED
@@ -1 +1 @@
1
- Djangoでのデータ集計分かりません。。。
1
+ 辞書オブジェクトをforループ回しても値取得できません。。。
test CHANGED
@@ -8,366 +8,212 @@
8
8
 
9
9
 
10
10
 
11
+ ### 困っていること
12
+
13
+ ・Djangoのtemplate/.htmlファイル内で、辞書オブジェクトをforループで回して、値を取得したいが、取得できない。
14
+
15
+ →辞書のforループで、キーを取得し、『 辞書['キー'] 』の形でキーに対する値を取得するコードを書いているが、
16
+
17
+ Could not parse the remainder: '['key']' from 'invoice['key']'というエラーが出てしまう。
18
+
19
+
20
+
21
+ ### 試したこと
22
+
23
+
24
+
25
+ 下記のように、htmlファイル上で、forループを回しましたが、エラーになります。
26
+
27
+ ```html
28
+
29
+
30
+
31
+ <body>
32
+
33
+ <h2>月別請求一覧</h2>
34
+
35
+ <table class="table">
36
+
37
+ <thead>
38
+
39
+ <tr>
40
+
41
+ <td>顧客ID</td>
42
+
43
+ <td>顧客名</td>
44
+
45
+ <td>ジャンル</td>
46
+
47
+ <td>合計レッスン数</td>
48
+
49
+ <td>請求金額</td>
50
+
51
+ </tr>
52
+
53
+ </thead>
54
+
55
+ <tbody>
56
+
57
+ {% for invoice in invoice_list %}
58
+
59
+ {% for key in invoice.keys %}
60
+
61
+ <tr>
62
+
63
+ <td>{{ invoice['key'] }}</td>
64
+
65
+ </tr>
66
+
67
+ {% endfor %}
68
+
69
+ {% endfor %}
70
+
71
+ </tbody>
72
+
73
+ </table>
74
+
75
+ <a href="{% url 'index' %}">メニューに戻る</a>
76
+
77
+ </body>
78
+
79
+
80
+
81
+ ```
82
+
83
+
84
+
85
+ 以下、ビュー関数です。
86
+
87
+
88
+
89
+ ```views
90
+
91
+ def invoice_index(request):
92
+
93
+ customers = Customer.objects.all()
94
+
95
+ genre_sum_template = {'英語': 0, 'ファイナンス': 0, 'プログラミング': 0}
96
+
97
+ invoice_list = []
98
+
99
+
100
+
101
+ for customer in customers:
102
+
103
+ price_sum = 0
104
+
105
+ genre_sum = genre_sum_template.copy()
106
+
107
+
108
+
109
+ lessons = customer.lesson_set.all()
110
+
111
+ lesson_sum = lessons.count()
112
+
113
+
114
+
115
+ for lesson in lessons:
116
+
117
+ columns = {}
118
+
119
+ genre = lesson.genre
120
+
121
+ genre_sum[genre] += 1
122
+
123
+
124
+
125
+ price = lesson.price
126
+
127
+ price_sum += price
128
+
129
+
130
+
131
+ columns['id'] = customer.id
132
+
133
+ columns['name'] = customer.name
134
+
135
+ columns['genre'] = genre_sum
136
+
137
+ columns['lesson'] = lesson_sum
138
+
139
+ columns['price'] = price_sum
140
+
141
+
142
+
143
+ invoice_list.append(columns)
144
+
145
+
146
+
147
+ return render(request, 'exam/invoice_index.html', {'customers': customers, 'columns':columns, 'invoice_list':invoice_list})
148
+
149
+ ```
150
+
151
+
152
+
11
153
  ### 実現したいこと
12
154
 
13
155
 
14
156
 
15
- 登録たデータを下記ののように集計したいです。
16
-
17
- ※プログラミング(2)というのは、プログラミングのレッスンを2回受けたという意味です。
18
-
19
- ![イメージ説明](5fddc19df6eeb4eef704440dfa4bfdbf.png)
20
-
21
-
22
-
23
- ### 困っていること
24
-
25
- ジャンルがうまく表示できない
26
-
27
- →色々と調べてみましたが、うまくいかない原因がmodel・views・templateのいずれにあるかのが分からず、途方に暮れています。
28
-
29
-
30
-
31
- ### 現在の状況
32
-
33
- CSSをまだ当てていないので、見にくいですが、現在は、下記のような状態です。
34
-
35
-
36
-
37
- ![![イメージ説明](630c7e97d5f8e1bdd5bba2f7df634362.png)
38
-
39
-
40
-
41
- もともと登録しているデータは下記のようなデータなので、
42
-
43
-
44
-
45
- ![イメージ説明](eb7a6767d91a0e856e7c5b9c67abf2db.png)
46
-
47
-
48
-
49
- 最終的には、
50
-
51
- ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
52
-
53
- 顧客ID  顧客名  ジャンル  合計レッスン数   請求金額
54
-
55
-   1     SQL   英語(2)    2       ・・・・
56
-
57
- ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
58
-
59
-
60
-
61
- のように表示したいです。
62
-
63
- ※英語(2)は英語のレッスンを2回受けたという意味です。
64
-
65
-
66
-
67
- ### 現状のソースコード
68
-
69
-
70
-
71
- ```models
72
-
73
- from django.db import models
74
-
75
- from django.utils import timezone
76
-
77
- from datetime import date
78
-
79
- from django.core.validators import MaxValueValidator, MinValueValidator
80
-
81
-
82
-
83
- class Customer(models.Model):
84
-
85
- Men = '男'
86
-
87
- Women = '女'
88
-
89
- GENDER = (
90
-
91
- (Men, '男'),
92
-
93
- (Women, '女'),
94
-
95
- )
96
-
97
-
98
-
99
- name = models.CharField('名前', max_length = 20)
100
-
101
- gender = models.CharField(
102
-
103
- '性別',
104
-
105
- max_length = 1,
106
-
107
- choices=GENDER,
108
-
109
- )
110
-
111
- age = models.IntegerField('年齢')
112
-
113
-
114
-
115
- class Lesson(models.Model):
116
-
117
- English = '英語'
118
-
119
- Finance = 'ファイナンス'
120
-
121
- Programing = 'プログラミング'
122
-
123
- GENRE = (
124
-
125
- (English, '英語'),
126
-
127
- (Finance, 'ファイナンス'),
128
-
129
- (Programing, 'プログラミング'),
130
-
131
- )
132
-
133
-
134
-
135
- customer = models.ForeignKey(Customer, verbose_name='顧客名', on_delete=models.PROTECT)
136
-
137
-
138
-
139
- genre = models.CharField(
140
-
141
- 'ジャンル',
142
-
143
- max_length = 255,
144
-
145
- choices=GENRE,
146
-
147
- default=English)
148
-
149
- lesson_day = models.DateField('受講日')
150
-
151
- lesson_time = models.PositiveIntegerField(
152
-
153
- '受講時間(h)',
154
-
155
- default = 1,
156
-
157
- validators=[
158
-
159
- MaxValueValidator(12),
160
-
161
- MinValueValidator(1)
162
-
163
- ]
164
-
165
- )
166
-
167
- price = models.IntegerField('支払金額', null=True)
168
-
169
-
170
-
171
-
172
-
173
- class Invoice(models.Model):
174
-
175
-
176
-
177
- customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
178
-
179
- lesson = models.ForeignKey(Lesson, on_delete=models.PROTECT)
157
+ イメージとては、下記のコードのような形で、キー対する値を取得、htmlファイルの<thead>の<td>に対応しデータを取得し、表示させた(※下記コードはイメージです。
158
+
159
+
160
+
161
+ ```html
162
+
163
+ <body>
164
+
165
+ <h2>月別請求一覧</h2>
166
+
167
+ <table class="table">
168
+
169
+ <thead>
170
+
171
+ <tr>
172
+
173
+ <td>顧客ID</td>
174
+
175
+ <td>顧客名</td>
176
+
177
+ <td>ジャンル</td>
178
+
179
+ <td>合計レッスン数</td>
180
+
181
+ <td>請求金額</td>
182
+
183
+ </tr>
184
+
185
+ </thead>
186
+
187
+ <tbody>
188
+
189
+ {% for invoice in invoice_list %}
190
+
191
+ {% for key in invoice.keys %}
192
+
193
+ <tr>
194
+
195
+ <td>{{ invoice['key'] }}</td>
196
+
197
+ <td>{{ invoice['key'] }}</td>
198
+
199
+ <td>{{ invoice['key'] }}</td>
200
+
201
+ <td>{{ invoice['key'] }}</td>
202
+
203
+ <td>{{ invoice['key'] }}</td>
204
+
205
+ </tr>
206
+
207
+ {% endfor %}
208
+
209
+ {% endfor %}
210
+
211
+ </tbody>
212
+
213
+ </table>
214
+
215
+ <a href="{% url 'index' %}">メニューに戻る</a>
216
+
217
+ </body>
180
218
 
181
219
  ```
182
-
183
-
184
-
185
- ```views
186
-
187
- from django.shortcuts import render, redirect
188
-
189
-
190
-
191
- from django.template.response import TemplateResponse
192
-
193
-
194
-
195
- from django.http import HttpResponseRedirect
196
-
197
- from django.http import Http404
198
-
199
- from django.http import HttpResponse
200
-
201
-
202
-
203
- from django.urls import reverse
204
-
205
-
206
-
207
- from exam.models import Customer
208
-
209
- from exam.models import Lesson
210
-
211
- from exam.models import Invoice
212
-
213
-
214
-
215
- from exam.forms import CustomerForm
216
-
217
- from exam.forms import CustomerEdit
218
-
219
- from exam.forms import LessonForm
220
-
221
- from exam.forms import LessonEdit
222
-
223
-
224
-
225
- from IPython import embed
226
-
227
- from IPython.terminal.embed import InteractiveShellEmbed
228
-
229
-
230
-
231
- ##途中は省略
232
-
233
-
234
-
235
- def invoice_index(request):
236
-
237
- customers = Customer.objects.all()
238
-
239
- lessons = Lesson.objects.all()
240
-
241
-
242
-
243
- return render(request, 'exam/invoice_index.html', {'customers': customers, 'lessons':lessons})
244
-
245
- ```
246
-
247
-
248
-
249
- ```html
250
-
251
- <body>
252
-
253
- <h2>月別請求一覧</h2>
254
-
255
-
256
-
257
- <table>
258
-
259
- <tr>
260
-
261
- <th>顧客ID</th><th>顧客名</th><th>ジャンル</th><th>合計レッスン数</th><th>請求金額</th>
262
-
263
- </tr>
264
-
265
- </table>
266
-
267
- {% for customer in customers %}
268
-
269
- <table>
270
-
271
- <tr>
272
-
273
- <td>{{ customer.id }}</td>
274
-
275
- <td>{{ customer.name }}</td>
276
-
277
- {% for lesson in lessons %}
278
-
279
- <td>{{ lesson.genre }}</td>
280
-
281
- {% endfor %}
282
-
283
- </tr>
284
-
285
- </table>
286
-
287
- {% endfor %}
288
-
289
-
290
-
291
- </body>
292
-
293
- ```
294
-
295
-
296
-
297
-
298
-
299
- ### 試したこと
300
-
301
-
302
-
303
- 下記のように辞書を用意して、各レッスンを受けた回数を集計し、htmlで表示させようとしましたが、
304
-
305
-
306
-
307
- ```views
308
-
309
- def invoice_index(request):
310
-
311
- customers = Customer.objects.all()
312
-
313
-
314
-
315
- genre_sum = {'英語': 0, 'ファイナンス': 0, 'プログラミング': 0}
316
-
317
-
318
-
319
- for customer in customers
320
-
321
- lesson = customer.lesson_set.all()
322
-
323
- for lesson in lessons:
324
-
325
- genre = lesson.genre
326
-
327
- genre_sum[genre] += 1
328
-
329
- ```
330
-
331
-
332
-
333
- 実際にシェルで試してみると、下記のように回数は数えることができたのですが、
334
-
335
- 顧客別に取得することができませんでした。
336
-
337
-
338
-
339
- ```
340
-
341
- In [17]: for customer in customers:
342
-
343
- ...: lessons = customer.lesson_set.all()
344
-
345
- ...: for lesson in lessons:
346
-
347
- ...: genre = lesson.genre
348
-
349
- ...: genre_sum[genre] += 1
350
-
351
- ...: print(genre_sum)
352
-
353
- ...:
354
-
355
- ...:
356
-
357
- {'英語': 1, 'ファイナンス': 0, 'プログラミング': 0}
358
-
359
- {'英語': 2, 'ファイナンス': 0, 'プログラミング': 0}
360
-
361
- {'英語': 2, 'ファイナンス': 1, 'プログラミング': 0}
362
-
363
- {'英語': 2, 'ファイナンス': 1, 'プログラミング': 1}
364
-
365
-
366
-
367
- ```
368
-
369
-
370
-
371
- 初歩的な質問かもしれませんが、とても困っているので、
372
-
373
- 是非、お力添え頂けないでしょうか