Django:formset中每个表单的不同表单字段小部件

时间:2013-04-11 10:41:39

标签: django django-forms

我正在努力寻找我想要的最佳方法。我可以为此提供一些帮助。

我有模型A和模型B.模型B有

modela = forms.ForeignKey(Model a)

我想创建一个视图,您可以在同一页面上编辑单个模型A和多个模型B. Django有这方面的形式,他们工作得很好。

虽然我有一个细节,但它会让事情变得微不足道。即 - 我希望小部件或模型B字段根据它们在同一对象的先前字段中所做的选择而不同。因为 - 基于类型,小部件必须是日期时间选择器输入或纯文本输入。

模型B看起来像这样:

class ModelB(models.Model):
    m0odela = models.ForeignKey(ModelA)
    target_value = models.CharField()
    target_type = models.CharField( choices = ( there are choices))
    target_threshold = models.CharField()

我知道我可以为formset提供自己的表单,我可以在该表单中执行此小部件分配。

但问题是,当formset没有实例/查询集时,我无法检查是否已为表单实例设置'target_type'。所以我必须在表单中基于self.data或self.initial来完成它。但form.__init__()中也没有self.initial。我可以使用的是self.data - 但这是原始request.POST或request.GET数据 - 其中包含所有键,如'mymodelb_set-0-target_type'。

所以我有点迷失在这里。我是否必须进行一些键解析并确定哪个-target_type属于当前表单并在那里获取所选值并根据此值分配小部件? 或者我是否必须创建自己的BaseInlineFormSet子类并以某种方式覆盖_construc_form?因此,该表单将具有** kwargs中的相关数据的初始密钥。

之前有人遇到过这类问题吗?

艾伦

1 个答案:

答案 0 :(得分:1)

我必须解决它,所以我解决了它的好坏我可以。

我创建了自己的内联formset的子类:

class MyInlineFormSet(BaseInlineFormSet):
    def _construct_form(self, i, **kwargs):
        initial = {}
        fname = '%s-%s-%s' % (self.prefix, i, 'important_field_name')
        initial['target_type'] = self.data[fname] if fname in self.data.keys() else 'km'
        kwargs.update({'initial':initial})
        form = super(MyInlineFormSet, self)._construct_form(i, **kwargs)
        return form

然后在表单类中:

class MyNiftyForm(forms.ModelForm):
    class Meta:
        model = MyAwesomeObject
        fields=('field_one', 'field_two', 'field_three')

    def __init__(self, *args, **kwargs):
        super(ServiceTargetForm, self).__init__(*args, **kwargs)
        if self.instance:
            if self.instance.field_one == 'date':
                self.fields['field_one'].widget.attrs['class'] = 'datepicker'
        if self.initial:
            if self.initial['field_one'] == 'date':
                self.fields['field_one'].widget.attrs['class'] = 'datepicker'

然后在视图中:

MySuperCoolFormSet = inlineformset_factory(ImportantObject, MyAwesomeObject, extra = 1, form = MyNiftyForm, formset = MyInlineFormSet)

它有效。

艾伦