Djangoで、質問投稿サイトを作成しています。
teratailのトップページでは、質問の一覧の中に各質問の回答数も表示しています。
同じことをしたいのですが、どのように作成していると思いますか?
私のサイトのモデルは、下記のとおりです。
python
1#modesl.py 2#質問を扱うクラス 3class Question(models.Model): 4 title = models.CharField(max_length=100) 5 content = models.TextField() 6 votes = models.IntegerField(default=0) 7 datetime = models.DateTimeField(auto_now=True) 8 9#回答を扱うクラス 10class Answer(models.Model): 11 question = models.ForeignKey(Question, on_delete=models.CASCADE) 12 content = models.TextField()
そして、質問一覧表示にあたっては、
python
1#views.py 2def index(request): 3 latest_question_list = Question.objects.order_by('-datetime')[:10] 4 context = { 5 'latest_question_list': latest_question_list, 6 } 7 return HttpResponse(template.render(context, request))
という形でデータを取り出し、レンダリングして表示させています。
最新のデータから10個を取り出して表示するようにしています。
私は、回答投稿数を表示するための方法として、下記の2つを思い付きました。
1.回答が投稿されると、Questionに回答数が記録されるようにする。
・Questionクラスに、
answercnt = models.IntegerField(default=0)
を登録しておく。
・回答投稿時に、views.pyにおいて、Answerクラスに保存するだけでなく、Questionクラスのanswercntに+1する。
(この方法は、質問の評価数をカウントする方法として既に使いました。votesというのがそれです。)
2.質問一覧表示をする時に、表示する質問に対する回答数をカウントして、表示する。
・モデル自体は、変更しない。
・views.pyにおいて、Questionモデルから、最新の10個の質問を取り出して、リスト化する。
・for文を使って、上記質問リストを順に見ていき、当該質問に対するAnswerをカウントし、answercntという変数に格納する。
・表示用のリストに、[[1つ目の質問タイトル, 1つ目の質問内容, 1つ目のanswercnt],[2つ目の質問タイトル, 2つ目の質問内容, 2つ目のanswercnt]、...]という形で格納する。
・上記表示用リストをテンプレートでレンダリングして表示する。
考えてみたコードは、下記のとおりです。
python
1#views.py 2def index(request): 3 latest_question_list = Question.objects.order_by('-datetime')[:10] #直近10個の質問に絞り込み 4 questionIdList = [] #上記10個の質問のIDを格納するリスト 5 for question in latest_question_list: 6 questionIdList.append(question.id) 7 displayList = [] #レンダリング用のリスト 8 for id in questionIdList: 9 contentListForQuestion = [] #質問毎に要素を格納するためのリスト 10 question = Question.objects.get(id=id) #IDから質問を呼び出す 11 contentListForQuestion.append(question.title) #質問タイトルを格納 12 contentListForQuestion.append(question.content) #質問内容を格納 13 contentListForQuestion.append(question.votes) #質問の評価を格納 14 contentListForQuestion.append(question.datetime) #質問日時を格納 15 contentListForQuestion.append(len(Answer.objects.filter(question=id)))) #質問に対する回答投稿数を格納 16 displayList.append(contentListForQuestion)
上記2つの方法のうち、1つ目は簡単に実装できると思います。しかし、なんとなく、スマートではないと思います。何らかのエラーで、実際の回答数と不整合が生じるリスクもあるので、嫌な感じもします。
そのため、私は、2つ目の方法の方が本来あるべき方法なのではないかと思います。ただ、Questionモデルのデータのみであれば、単純に表示用のリストを作成することができたのに、複数のモデルからデータを引っ張ってくるために、上記のように急に複雑になってしまうので、もっとシンプルな方法が存在するのではないかと思いました。
複数の関連するモデルからデータを引っ張ってきて表示する際の、ベストプラクティスのようなものがあれば、ご教示頂きたいです。
よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/04/09 03:03