我正在努力寻找我想要的最佳方法。我可以为此提供一些帮助。
我有模型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中的相关数据的初始密钥。
之前有人遇到过这类问题吗?
艾伦
答案 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)
它有效。
艾伦