如果发生错误,django 中的 CreateView 上的 form_valid 是否会回滚保存?

Does form_valid on a CreateView in django roll back a save if an error occurs?

我有一个带有 form_valid() 方法的 ModelForm 的 CreateView,它很早就调用了 form.save()(以便我可以获得对象的 ID),然后继续做一些其他的事情(创建一些相关的对象,并发送一些电子邮件)。

def form_valid(self, form):
    context = self.get_context_data()
    preferences_formset = context['preferences_formset']
    if preferences_formset.is_valid():
        student = form.save()
        ...
        send_email_one()
        send_email_two()
        send_email_three()
        return HttpResponseRedirect(self.get_success_url())

最近发现,在调用send_email_three时,后面的一些处理出现了一些错误,导致在某些情况下出现未处理的异常。我从我的日志中可以看到正在调用send_email_one和send_email_two,异常发生在send_email_three。但是,发生这种情况时,我无法在数据库中找到对象。我的印象是 form.save() 应该在数据库中创建并保存对象 - 是这种情况还是如果 form_valid 函数稍后出错,它是否会回滚保存?

我正在使用 django 1.8.17

PS:是的,我知道我应该把邮件放在延迟任务中;这将在以后实施。

您可以使用 @transaction.atomic 装饰器

https://docs.djangoproject.com/en/1.10/topics/db/transactions/#controlling-transactions-explicitly

这取决于ATOMIC_REQUESTS setting. Setting it to True will trigger the behaviour described in the docs:

Before calling a view function, Django starts a transaction. If the response is produced without problems, Django commits the transaction. If the view produces an exception, Django rolls back the transaction.