【问题标题】:Django: Different form field widget per form in formsetDjango:表单集中每个表单的不同表单字段小部件
【发布时间】:2013-04-03 12:36:08
【问题描述】:

我正在尝试找到我想要的最佳方法。我可以为此提供一些帮助。

我有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 提供我自己的表单,并且我可以在该表单中执行此小部件分配。

但问题是,当表单集没有实例/查询集时,我无法检查是否为表单实例设置了“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 中相关数据的初始键。

以前有人遇到过这种问题吗?

艾伦

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    好吧,我必须解决它,所以我尽可能地解决了它。

    我创建了自己的内联表单集子类:

    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)
    

    而且它有效。

    艾伦

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 2015-10-06
      • 2010-12-26
      • 1970-01-01
      • 2012-06-04
      • 1970-01-01
      • 2014-03-12
      • 2011-05-30
      • 2012-08-16
      相关资源
      最近更新 更多