【发布时间】:2021-09-12 02:46:38
【问题描述】:
我正在使用 Django 的 BaseFormset 中的 empty_forms 来动态地将内联表单附加到父级。适用于编辑/创建视图。
但是现在我需要从本质上实现一个 DuplicateView。我基本上使用的是 CreateView,在 get_context_data() 中对其进行调整,以使用要复制的对象填充它。像这样的:
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
self.object = self.model.objects.get(pk=self.kwargs["pk"])
logger.info(f"ProduitDuplicateView.get_context_data - object id/code: {self.object.pk} {self.object.no_prod}")
if self.request.POST:
# code
else:
ctx["form"] = ProduitForm(instance=self.object)
fourprodfrmset = FourProdFormSet(instance=self.object)
casefrmset = CaseFormSet(instance=self.object)
我确实需要将实例设置为 self.object,因为我想填充现有的内联表单,以便使用相关数据复制基础对象。但是,该内联表单包含一个指向父对象的外键,默认设置为父对象的 pk 值。对于表单实例,我将其设置为 none,如下所示:
for f in formset:
try:
f.initial.pop("fk_produit")
f.fields["fk_produit"].initial = None
except KeyError as ex:
logger.info(f"There was no fk_produit in form.initial for this form of the formset")
这适用于表单实例。但是,我还需要对 empty_form 执行相同操作 - 否则,当我将 emtpy_form 附加到我的内联表单集时,它会设置为基础对象的 pk。这意味着以这种方式保存新的内联表单会导致错误(类似于“内联表单的 id 与父表单的 id 不同”)。
所以我尝试这样设置:
for formset in [fourprodfrmset, casefrmset]:
try:
formset.empty_form.fields["fk_produit"].initial = None
except KeyError as ex:
logger.info(f"Couldn't remove fk_produit initial value in formset empty_form")
但是,由于某种原因,它没有任何效果 - 如果我在方法结束时调试它,formset 的 emtpy_form 字段“fk_produit”仍然有它的基础值(例如基础对象的值) )。
那么.....我如何修改 empty_form 字段的值?最好在视图中,因为那是我处理所有这些恶作剧的地方。
我想我当然可以按模板来做,但这需要更多的工作......我真的更热衷于在视图中处理它。有什么想法吗?
【问题讨论】: