0

I'm trying to build a little website where users can set up tournaments and then invite players for their tournaments.

These are my Tournament and Invite models:

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')

And then these are my Views:

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)

I'm doing something wrong because the tourney_id is not being set on form.instance.invited_for ; instead when I click submit I get Django error saying "KeyError at /tourney/inviteplayers/ 'tourney_id'"

Any help much appreciated!

tinkerbits
  • 67
  • 7
  • Hi, it would seem as though you are not setting your session as you have not called to update a session. Take a look into that. –  Jun 17 '21 at 10:21
  • Hi Stackdon; I see your point but I'm actually not too sure how to call to update a session. I can imagine I'd have to do something like: class InvitePlayersView(MakeTourneyView): [code to call update_session method and return Tournament object] def form_valid(self, form): [code to inject Tournament object into form instance] How to call the update_session in the InvitePlayersView is not clear to me though. – tinkerbits Jun 17 '21 at 11:45
  • Found a slightly hacky solution: - pass the tourney_id in the url to InvitePlayersView (in urls.py) - use that url for the get_success_url method in the MakeTourneyView - in InvitePlayersView's form_valid method, get the current path using self.request.path, and then strip out the tourney_id using python's strip() - still in InvitePlayersView's form_valid method, pass the tourney_id to a Tournament queryset to get the tourney obj, and pass that to form.instance.invited_for prior to doing form.save() It works but it really feels hacky so constructive feedback is still very welcome :) – tinkerbits Jun 17 '21 at 15:45

1 Answers1

0

Try the following with your problem.

If you read more in the documentation about it you can access the current instance like below.

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)
  • Progress, i get a different error now :D "'Invite' object has no attribute 'update_session'". Really appreciate your help stackdon :) – tinkerbits Jun 17 '21 at 12:15