View間でデータを受け渡す方法

- django

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先に渡している。 ベストプラクティスではない気がするが、参考までに。