【问题标题】:Django: Saving new object with form and inline formset (transaction managment)Django:使用表单和内联表单集保存新对象(事务管理)
【发布时间】:2020-05-12 14:10:16
【问题描述】:

我有一个表单,我在其中创建了一个新的“父”对象,恰好是一个类型为 A 的子对象和 n 个类型为 B 的子对象(n 也可以是 0)。我用一个表单和两个内联表单集来做到这一点。

我已在设置中设置'ATOMIC_REQUESTS': True。

我正在使用基于函数的视图。保存数据的代码是这样的:

if form.is_valid():      
    parent = form.save();
    formsetA = AFormset(request.POST, instance=parent)
    formsetB = BFormset(request.POST, instance=parente)
    if formsetA.is_valid():
        # save first form in inline formset (there always only is one)
        # and then assign meta data
        a = formset[0].save()
        if formsetB.is_valid():
            for b in formsetB:
                if b.is_valid():
                    b.save()

检查父级是否有效,保存并将其设置为内联表单集的实例。然后检查内联表单集。如果表单无效,我会重定向回表单。也不例外。

问题是如果inlineformset 无效,它会返回到表单,但父级已经保存并且事务没有回滚。如果我在重定向回表单之前手动回滚事务,则会出现异常:

An error occurred in the current transaction. You can't execute queries until the end of the 'atomic' block.

我假设我不能在原子块内手动回滚?

我的主要问题是我应该如何正确处理这种情况,例如。同时保存父母和孩子?

【问题讨论】:

    标签: django transactions inline-formset


    【解决方案1】:

    解决直接问题的方法是不提交父表单保存,然后在提交父表单之前首先检查表单集的有效性:

    if form.is_valid():      
        parent = form.save(commit=False);
        formsetA = AFormset(request.POST, instance=parent)
        formsetB = BFormset(request.POST, instance=parente)
        if formsetA.is_valid() and formsetB.is_valid():
            #formsets are valid, parent can be saved
            # this assumes if formset is valid, all contained forms are too
            parent.save()
            a = formset[0].save()
            for b in formsetB:                    
                b.save()
    

    【讨论】:

      【解决方案2】:

      我发现,我在不同的模型中有相同的字段名称,所以保存出错了!重命名后所有工作

      【讨论】:

        猜你喜欢
        • 2016-10-09
        • 1970-01-01
        • 2019-09-02
        • 1970-01-01
        • 2015-02-28
        • 2020-01-12
        • 1970-01-01
        • 2013-04-07
        • 1970-01-01
        相关资源
        最近更新 更多