Py学习  »  Django

Django transaction.atomic()不工作

Barburka • 5 年前 • 1905 次点击  

我对这个代码有问题:

PhoneNumberFormSet = inlineformset_factory(Person, PhoneNumber, fields=('phone_number',), 
can_delete=False, extra=1)

EmailAddressFormSet = inlineformset_factory(Person, EmailAddress, fields=('email_address',), 
can_delete=False, extra=1)

class PersonCreateView(CreateView):

    form_class = PersonForm
    success_url = reverse_lazy('person-list')
    template_name = 'contacts/person_create.html'

    def get_context_data(self, **kwargs):
        data = super(PersonCreateView, self).get_context_data(**kwargs)
        data['phone_formset'] = PhoneNumberFormSet(self.request.POST or None)
        data['email_formset'] = EmailAddressFormSet(self.request.POST or None)
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        phone_formset = context['phone_formset']
        email_formset = context['email_formset']
        with transaction.atomic():
            o = form.save() # <--- this object is saved even when formsets below are not valid
            condition = phone_formset.is_valid() and email_formset.is_valid()
            if not condition:
                return render(self.request, self.template_name, self.get_context_data())
            phone_formset.instance = o
            phone_formset.save()
            email_formset.instance = o
            email_formset.save()
        return super(PersonCreateView, self).form_valid(form)

transaction.atomic()正在保存对象“o”,即使phone\u formset或email\u formset无效并且view呈现有错误的表单(不应保存对象)

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/51956
 
1905 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Gasanov
Reply   •   1 楼
Gasanov    5 年前

它不起作用,因为原子事务只有在引发异常时才会回滚。在您的情况下,您只需返回普通响应对象,它不会触发回滚,从而提交到数据库。

有关中的原子事务的详细信息 django docs .

将您的代码更改为类似这样的代码(未确认它是否正常工作,但链接文档中有此类示例):

from django.core.exceptions import ValidationError

def form_valid(self, form):
        context = self.get_context_data()
        phone_formset = context['phone_formset']
        email_formset = context['email_formset']
        try:
            with transaction.atomic():
                o = form.save() # <--- this object is saved even when formsets below are not valid
                condition = phone_formset.is_valid() and email_formset.is_valid()
                if not condition:
                    raise ValidationError
                phone_formset.instance = o
                phone_formset.save()
                email_formset.instance = o
                email_formset.save()
        except ValidationError:
            return render(self.request, self.template_name, self.get_context_data())
        return super(PersonCreateView, self).form_valid(form)