Django:将会话信息传递给下一个模板和视图

Posted

技术标签:

【中文标题】Django:将会话信息传递给下一个模板和视图【英文标题】:Django : pass session information to next template & view 【发布时间】:2021-09-02 02:29:57 【问题描述】:

我正在尝试建立一个小网站,用户可以在其中设置锦标赛,然后邀请玩家参加他们的锦标赛。

这些是我的锦标赛和邀请模型:

class Tournament(models.Model):
    tourney_name = models.CharField(max_length=200, null=False, blank=False) 
    event = models.ForeignKey(NewsArticle, on_delete=models.DO_NOTHING, related_name='tourneys')
    host_user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    # player_count_limit = models.PositiveIntegerField(validators=[MaxValueValidator(100)])
    player_join_deadline = models.DateField()
    fantasy_team_size = models.PositiveIntegerField(validators=[MinValueValidator(5),MaxValueValidator(15)])
    created_dt = models.DateTimeField(auto_now_add=True)
    last_modified_dt = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.tourney_name

    def get_absolute_url(self):
        return reverse('home')

class Invite(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    email = models.CharField(max_length=320, null=False, blank=False, validators=[EmailValidator],)
    invited_by = models.ForeignKey(get_user_model(), on_delete=models.DO_NOTHING)
    invited_for = models.ForeignKey(Tournament, on_delete=models.DO_NOTHING)
    created_dt = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.email

    def get_absolute_url(self):
        return reverse('home')

然后这些是我的观点:

class MakeTourneyView(CreateView):
    template_name = 'make_tourney.html'
    model = Tournament
    form_class = MakeTourneyForm    

    def form_valid(self, form):
        form.instance.host_user = self.request.user
        form.save()
        return super(MakeTourneyView, self).form_valid(form)

    def get_success_url(self):
        return reverse('invite_players')
        #return reverse('invite_players', kwargs='tourney_id': self.object.id)

    def update_session(self):
        tourneyobj = self.get_object()
        self.request.session['tourney_id'] = tourneyobj.id
        return self.request.session['tourney_id']


class InvitePlayersView(CreateView):
    template_name = 'invite_players.html'
    model = Invite
    form_class = InvitePlayerForm

    def form_valid(self, form):
        tourney_id = self.request.session['tourney_id']
        form.instance.invited_for = Tournament.objects.filter(id=tourney_id).get()
        form.instance.invited_by = self.request.user
        form.save()
        return super(InvitePlayersView, self).form_valid(form)

我做错了,因为 tourney_id 没有设置在 form.instance.invited_for 上;相反,当我单击提交时,我收到 Django 错误消息“KeyError at /tourney/inviteplayers/ 'tourney_id'"

非常感谢任何帮助!

【问题讨论】:

您好,您似乎没有设置会话,因为您没有调用更新会话。看看那个。 嗨斯塔克登;我明白你的意思,但我实际上不太确定如何调用来更新会话。我可以想象我必须执行以下操作: class InvitePlayersView(MakeTourneyView): [调用 update_session 方法并返回 Tournament 对象的代码] def form_valid(self, form): [将 Tournament 对象注入表单实例的代码] 如何调用不过,我不清楚 InvitePlayersView 中的 update_session。 找到了一个稍微有点 hacky 的解决方案: - 将 url 中的 tourney_id 传递给 InvitePlayersView(在 urls.py 中) - 将该 url 用于 MakeTourneyView 中的 get_success_url 方法 - 在 InvitePlayersView 的 form_valid 方法中,获取当前路径使用 self.request.path,然后使用 python 的 strip() 去除 tourney_id - 仍然在 InvitePlayersView 的 form_valid 方法中,将 tourney_id 传递给 Tournament 查询集以获取锦标赛 obj,然后在执行之前将其传递给 form.instance.invited_for form.save() 它可以工作,但它真的感觉很老套,所以仍然非常欢迎有建设性的反馈:) 【参考方案1】:

针对您的问题尝试以下方法。

如果您在文档中阅读了更多关于它的信息,您可以访问当前实例,如下所示。

class InvitePlayersView(CreateView):
    template_name = 'invite_players.html'
    model = Invite
    form_class = InvitePlayerForm

    def form_valid(self, form):
        tourney_id = form.instance.update_session()
        form.instance.invited_for = Tournament.objects.filter(id=tourney_id).get()
        form.instance.invited_by = self.request.user
        form.save()
        return super(InvitePlayersView, self).form_valid(form)

【讨论】:

进度,我现在得到一个不同的错误:D“'邀请'对象没有属性'update_session'”。非常感谢您的帮助 stackdon :)

以上是关于Django:将会话信息传递给下一个模板和视图的主要内容,如果未能解决你的问题,请参考以下文章

Django:从模板中访问会话变量?

将js变量传递给django视图[重复]

如何将变量传递给下一个视图?

将变量传递给下一个视图控制器

iOS:将手势传递给下面的视图

将触摸传递给下的视图