Django如何保存自定义表单集

Posted

技术标签:

【中文标题】Django如何保存自定义表单集【英文标题】:Django how to save a custom formset 【发布时间】:2010-11-26 17:03:10 【问题描述】:

我已经编写了以下自定义表单集,但对于我来说,我不知道如何保存表单。我搜索了 Django 文档并进行了广泛的搜索,但没有一种解决方案有效。很多兔子洞,但没有肉;-) 有人能指出我正确的方向吗?

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

【问题讨论】:

【参考方案1】:

只有模型表单和表单集带有save() 方法。常规表单不附加到模型,因此您必须自己存储数据。来自 Django 邮件列表的How to save a formset? 有一个从常规表单集中保存数据的示例。

编辑:您始终可以按照 gbc 的建议将 save() 方法添加到常规表单或表单集。他们只是没有内置的。

我在您的代码 sn-ps 中没有看到 TeamStat 模型,但如果您有,您的 forms.py 应该如下所示:

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)

请参阅 Django 文档中的 Creating forms from models

【讨论】:

【参考方案2】:

在您的自定义表单中,您需要添加一个 save() 方法,根据需要将表单数据填充到您的模型中。表单中输入的所有数据都将在名为 clean_data[] 的哈希中提供。

例如:

def save(self):
    teamStat = TeamStat(game_id=self.cleaned_data['game_id'],team_id=self.cleaned_data['team_id'])
    teamStat.save()
    return teamStat

【讨论】:

很高兴它有帮助,我刚刚开始我的第一个 Django 项目,并且也在解决这些问题。

以上是关于Django如何保存自定义表单集的主要内容,如果未能解决你的问题,请参考以下文章

如何使用django自定义表单保存多个到多个字段

自定义 Django 表单不保存

使用注册表单添加到自定义用户字段(django)

在 Django 中使用自定义外键字段保存表单中的数据

Django:如何在管理表单中获取当前用户?

如何在 django 模型表单中添加自定义字段?