使用 formset 元素保存对象并使用新的相关元素制作副本

Saving an object with formset element AND making a copy with new related elements

我正在尝试在具有外键(作为内联表单集管理)的对象上进行创建和更新之间的某种混合。

更新表单(及其相关的表单集表单)中的父对象工作正常。我还可以将该父对象的副本保存为数据库中的新实例,效果很好。但是我似乎无法弄清楚如何将表单集的副本也制作为新的独立对象。

基本上,一旦一切都说完了,我想要:

我目前可以修改 Foo,创建 FooCopy,以及将 bar_1 修改为 bar_n...但不能创建 bar_1_copy 等

例如:

class SoumissionUpdateView(LoginRequiredMixin, SideBarMixin, UpdateView):
    def form_valid(self, form, formset):
        # that saves any modification to the initial object, as well as the elements in the formset
        self.object = form.save()
        formset.instance = self.object
        formset.save()

        # this saves the parent object as a new instance. However no new formset objects are created in the db.
        self.object.pk = None
        self.object.save()
        formset.instance = self.object
        formset.save()                          # since those should be 2 different sets of instance in db
        return HttpResponseRedirect(self.get_success_url())

我的理解是因为第二次保存之前的formset引用了一个新的实例,所以应该将它们保存为新的对象。但是它似乎没有保存任何东西(因为表单集,即使在第二次调用 formset.save() 之后,仍然引用原始父实例)。

关于我应该如何保存引用原始父副本的独立表单集对象的任何建议?

结果是检查 BaseInlineFormset 的定义(django.forms.model.py 第 891 行)揭示了一个方便的 kwargs:

class BaseInlineFormSet(BaseModelFormSet):
    """A formset for child objects related to a parent."""
    def __init__(self, data=None, files=None, instance=None,
                 save_as_new=False, prefix=None, queryset=None, **kwargs):

因此,在这种情况下,我实际上传递给 form_valid() 2 格式集,在 def post():

def post(self, request, *args, **kwargs):
    self.object = self.get_object()
    form = self.get_form(self.get_form_class())
    formset = DetSoumFormset(self.request.POST, instance=self.object)
    formset_copy = DetSoumFormset(self.request.POST, instance=self.object, save_as_new=True)
    if form.is_valid() and formset.is_valid() and formset_copy.is_valid():
        return self.form_valid(form, formset, formset_copy)

然后我代替上面问题中的第 2 个 formset.save(),而是 od formset_copy.save().

是的。