views:

692

answers:

2

I've written the following custom formset, but for the life of me I don't know how to save the form. I've searched the Django docs and done extensive searches, but no one solution works. Lots of rabbit holes, but no meat ;-) Can someone point me in the right direction?

// views.py partial //

@login_required

def add_stats(request, group_slug, team_id, game_id, template_name = 'games/stats_add_form.html'):

    if request.POST:

        formset = AddStatsFormSet(group_slug=group_slug, team_id=team_id, game_id=game_id, data=request.POST)

        if formset.is_valid():

            formset.save()

            return HttpResponseRedirect(reverse('games_game_list'))

        else:

            formset = TeamStatFormSet(group_slug=group_slug, team_id=team_id, game_id=game_id)

        return render_to_response(template_name, {'formset': formset,})


// modles.py partial //

class PlayerStat(models.Model):

    game = models.ForeignKey(Game, verbose_name=_(u'sport event'),)
    player = models.ForeignKey(Player, verbose_name=_(u'player'),)
    stat = models.ForeignKey(Stat, verbose_name=_(u'statistic'),)
    total = models.CharField(_(u'total'), max_length=25, blank=True, null=True)

    class Meta:
        verbose_name = _('player stat')
        verbose_name_plural = _('player stats')
        db_table     = 'dfusion_playerstats'

        def __unicode__(self):
            return u'%s' % self.player


// forms.py

class TeamStatForm(forms.Form):

    total = forms.IntegerField()


class BaseTeamStatsFormSet(BaseFormSet):

    def __init__(self, *args, **kwargs):
     self.group_slug = kwargs['group_slug']
     self.team_id = kwargs['team_id']
     self.game_id = kwargs['game_id']
     self.extra = len(Stat.objects.filter(group__slug=self.group_slug))
     del kwargs['group_slug']
     del kwargs['game_id']
     del kwargs['team_id']
     super(BaseTeamStatsFormSet, self).__init__(*args, **kwargs)

    def add_fields(self, form, index):
     super(BaseTeamStatsFormSet, self).add_fields(form, index)
     form.fields["stat"] = forms.ModelChoiceField(queryset = Stat.objects.filter(group__slug=self.group_slug))
     form.fields["game"] = forms.ModelChoiceField(queryset = Game.objects.all())
     form.fields["team"] = forms.ModelChoiceField(queryset = Team.objects.all())
     form.fields["game"].initial = self.game_id
     form.fields["team"].initial = self.team_id

TeamStatFormSet = formset_factory(TeamStatForm, BaseTeamStatsFormSet)
+3  A: 

Only model forms and formsets come with a save() method. Regular forms aren't attached to models, so you have to store the data yourself. How to save a formset? from the Django mailing list has an example of saving data from a regular formset.

Edit: You can always add a save() method to a regular form or formset as gbc suggests. They just don't have one built-in.

I don't see a TeamStat model in your code snippets, but if you had one, your forms.py should look something like this:

class TeamStatForm(forms.ModelForm):
 total = forms.IntegerField()

 class Meta:
  model = TeamStat


class BaseTeamStatsFormSet(BaseModelFormSet):

 def __init__(self, *args, **kwargs):
  self.group_slug = kwargs['group_slug']
  self.team_id = kwargs['team_id']
  self.game_id = kwargs['game_id']
  self.extra = len(Stat.objects.filter(group__slug=self.group_slug))
  del kwargs['group_slug']
  del kwargs['game_id']
  del kwargs['team_id']
  super(BaseTeamStatsFormSet, self).__init__(*args, **kwargs)

 def add_fields(self, form, index):
  super(BaseTeamStatsFormSet, self).add_fields(form, index)
  form.fields["stat"] = forms.ModelChoiceField(queryset = Stat.objects.filter(group__slug=self.group_slug))
  form.fields["game"] = forms.ModelChoiceField(queryset = Game.objects.all())
  form.fields["team"] = forms.ModelChoiceField(queryset = Team.objects.all())
  form.fields["game"].initial = self.game_id
  form.fields["team"].initial = self.team_id

TeamStatFormSet = modelformset_factory(TeamStatForm, BaseTeamStatsFormSet)

See Creating forms from models from the Django docs

Selene
+3  A: 

In your custom forms, you'll need to add a save() method that stuffs the form data into your models as needed. All of the data entered in the form will be available in a hash called cleaned_data[].

For example:

def save(self):
    teamStat = TeamStat(game_id=self.cleaned_data['game_id'],team_id=self.cleaned_data['team_id'])
    teamStat.save()
    return teamStat
gbc
This worked out great. Thanks for pointing me in the right direction.
Terry Owen
Glad it helped, I'm just starting on my first Django project and working through these issues also.
gbc