更改非父模型的 inlineformset 中模型字段的查询集
Posted
技术标签:
【中文标题】更改非父模型的 inlineformset 中模型字段的查询集【英文标题】:Change queryset of model field in inlineformset of non parent model 【发布时间】:2013-10-18 19:33:44 【问题描述】:我正在使用内联表单集,并且需要在实例化表单集时更改非父模型的表单字段之一的查询集。
class Foo(Model):
name = models.TextField()
class Bar(Model):
foo = models.ForiegnKey(Foo)
other_model = models.ForeignKey(OtherModel)
class BarForm(ModelForm):
class Meta:
model=Bar
foo = Foo.object.get(id=1)
FormSet = inlineformset_factory(Foo, Bar, form=BarForm)
formset = FormSet(instance=foo)
根据直到我输入视图代码才确定的 foo 的值,我需要为表单集中的所有表单更改 BarForm 中“other_model”字段的查询集。有没有办法做到这一点?
【问题讨论】:
【参考方案1】:如果我对您的理解正确,您可以这样做...您可以覆盖BaseInlineFormSet
,然后在表单集中的每个表单上手动设置该字段的查询集。
所以在你的 forms.py 中,你会这样做:
class BaseBarFormSet(BaseInlineFormSet):
def __init__(self, other_model_queryset, *args, **kwargs):
super(BaseInlineFormSet, self).__init__(*args, **kwargs)
for form in self.forms:
form.fields['other_field'].queryset = other_model_queryset
注意 __init__ 的第一个参数是您要设置的查询集。
然后在您看来,您只需相应地修改当前代码。在工厂函数中传入那个新的 BaseBarFormSet:
FormSet = inlineformset_factory(Foo, Bar, form=BarForm, formset=forms.BaseBarFormSet) # notice formset=forms.BaseBarFormSet
然后将您想要的其他字段的查询集传递给工厂函数创建的实际FormSet
类:
formset = FormSet(OtherModel.objects.filter(…), instance=foo) #notice the first parameter
Formset 有时非常复杂,所以希望这是有道理的……如果您有问题,请告诉我。
【讨论】:
这似乎解决了查询集的问题。然而,即使它没有改变,我的额外表单也会出现验证错误。我的印象是表单集不会这样做。来自 django 文档“表单集足够聪明,可以忽略未更改的额外表单。” 你是对的。如果表单确实为空,则不应出现错误。您的表单上没有任何默认值吗?以上是关于更改非父模型的 inlineformset 中模型字段的查询集的主要内容,如果未能解决你的问题,请参考以下文章
django - 具有多个 ForeignKey 的 inlineformset_factory
formset、inlineformset_Factory 和 kwargs
在 Django inlineformset_factory 中过滤查询集