View間でデータを受け渡す方法
Djangoでview間でデータを受け渡す方法
発生した事案
現在スプラトゥーンのブキのサブ、スペシャルを当てるクイズアプリを作成している。 その中で、ブキのオブジェクトをランダムに取得し、そのidをrender先に渡したいという状況が発生した。
課題
get_context_data
メソッド内でDBからランダムにweapon
オブジェクトを取得し、そのidをレンダリング先に渡したい。
Djangoでtemplateにデータを受け渡す方法として、メソッドget_context_data
を定義する方法がある。しかし、view間でデータを受け渡す方法は見つからなかった。
解決方法
get_context_data内でsessionに変数を加える
具体的に説明する。
models.py
class SubWeapon(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField('名前', max_length=64)
class Special(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField('名前', max_length=64)
class Weapon(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField('ブキ名', max_length=64)
sub = models.ForeignKey(
SubWeapon, on_delete=models.PROTECT, related_name='weapon')
special = models.ForeignKey(
Special, on_delete=models.PROTECT, related_name='weapon')
views.py
class SubSpQuizView(generic.FormView):
template_name = 'spla/subsp_quiz.html'
model = Weapon
form_class = SubSpQuizForm
success_url = reverse_lazy('spla:subsp_quiz_result')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["weapon"] = random.choice(Weapon.objects.all())
# 答えとなるサブ、スペシャルのidをsessionに渡す
self.request.session["weapon"] = context["weapon"].id
self.request.session["sub"] = context["weapon"].sub.id
self.request.session["sp"] = context["weapon"].special.id
return context
def form_valid(self, form):
# 正解と解答をcontextに格納
context = {
'weapon': Weapon.objects.get(id=self.request.session["weapon"]),
'sub_correct': SubWeapon.objects.get(id=self.request.session["sub"]),
'sp_correct': Special.objects.get(id=self.request.session["sp"]),
'sub_ans': SubWeapon.objects.get(id=form.data["sub_choices"]),
'sp_ans': Special.objects.get(id=form.data["sp_choices"]),
}
if context['sub_correct'] == context['sub_ans'] and context['sp_correct'] == context['sp_ans']:
context['judge'] = True
else:
context['judge'] = False
return render(self.request, 'spla/subsp_quiz_result.html', context)
modelとviewは以上の通り。get_context_data
メソッド内でself.request.session
に値を渡し、form_valid
メソッド内で値をcontext
に含めてrender先に渡している。
ベストプラクティスではない気がするが、参考までに。