简体   繁体   中英

Django 1.9 FormView never reach get_context_data

I have a FormView called LeagueTransferView based on a form LeagueTransferForm.

I'm trying to override get_context_data to add extra players to render in the template.

But get_context_data is never reached. It's working fine on other views like, DetailView, ListView,...

I'm missing something?

Below my configuration

View

class LeagueTransferView(FormView):
    template_name = 'hockey/league/transfer_market.html'
    form_class = LeagueTransferForm
    success_url = ''

    def get_context_data(self, **kwargs):
        print('----NEVER REACHED----')
        context = super(LeagueTransferView, self).get_context_data(**kwargs)
        petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
        context['players'] = Player.objects.filter(leagues=self.kwargs['pk']).exclude(teams=petitioner)
        return context

    def get(self, request, *args, **kwargs):
        petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
        form = self.form_class(initial={'league': self.kwargs['pk'], 'petitioner': petitioner})
        form.fields['offered_player'].queryset = petitioner.players
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            transfer = form.save(commit=False)
            team = Team.objects.filter(league=transfer.league, players__in=[transfer.requested_player])
            if not team:  # free agent
                transfer.status = 1
                messages.success(request, _('transfer succeeded'))
            else:
                print(team)
                transfer.player_owner = team[0]
                if transfer.petitioner.user is None:  # bot team
                    transfer.status = 1
                    messages.success(request, _('transfer succeeded'))
                else:
                    messages.success(request, _('transfer waiting for confirmation by player owner'))
            transfer.save()
            return HttpResponseRedirect(reverse('hockey_dashboard'))

        petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
        form.fields['offered_player'].queryset = petitioner.players
        return render(request, self.template_name, {'form': form})

FORM

class LeagueTransferForm(forms.ModelForm):
    class Meta:
        model = Transfer
        fields = ['league', 'requested_player', 'offered_player', 'player_owner', 'petitioner']
        labels = {
            'requested_player': _('Requested player'),
            'offered_player': _('Offered player'),
        }
        widgets = {
            'requested_player': forms.HiddenInput,
            'league': forms.HiddenInput,
            'player_owner': forms.HiddenInput,
            'petitioner': forms.HiddenInput
        }

Your code is never reaching get_context_data() because you have overridden the get() method and not calling the get_context_data() function there. You need to manually call the get_context_data() function at the time of passing context to render() in your code.

Instead of doing that, i would suggest you to try the below approach where instead of overrriding get() and returning your custom response, you only override what is necessary and let Django handle the rest.

class LeagueTransferView(FormView):
    template_name = 'hockey/league/transfer_market.html'
    form_class = LeagueTransferForm
    success_url = ''

    def get_context_data(self, **kwargs):
        context = super(LeagueTransferView, self).get_context_data(**kwargs)
        context['players'] = Player.objects.filter(leagues=self.kwargs['pk']).exclude(teams=self.petitioner)
        return context

    def get_initial(self):
        initial = super(LeagueTransferView, self).get_initial()
        initial['league'] = self.kwargs['pk'] # add custom data to initial
        initial['petitioner'] = self.petitioner # add custom data to initial
        return initial

    def get_form(self, form_class=None):
        form = super(LeagueTransferView, self).get_form(form_class)
        # override the queryset
        form.fields['offered_player'].queryset = self.petitioner.players 
        return form

    def get(self, request, *args, **kwargs):
        # only perform 1 query to get 'petitioner'
        self.petitioner = get_object_or_404(Team, user=self.request.user.profile, league=self.kwargs['pk'])
        return super(LeagueTransferView, self).get(request, *args, **kwargs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM