首页 > 解决方案 > Django:is_valid 正在改变 self.object

问题描述

在我的代码中,您会看到两个打印语句。在我的表单中,先前保存在数据库中的值为emailprevious@gmail.com. 我在表格中输入的新值是emailnew@gmail.com.

我从印刷声明中得到的预期结果:

emailprevious@gmail.com self.object.email
emailprevious@gmail.com self.object.email 2

实际结果:

emailprevious@gmail.com self.object.email
emailnew@gmail.com self.object.email 2

似乎self.attendee_form.is_valid(),正在改变 self.object。我找不到在 Django 源代码中定义的行为is_valid()你能解释为什么self.object会发生变化吗?

class AssignAttendee(SuccessMessageMixin, SingleObjectMixin, TemplateView):
    template_name = 'attendees/front/assign_attendee.html'
    success_message = _("Attendee has been successfully updated.")

    def get_object(self):
        return get_object_or_404(
            Attendee,
            ticket_reference=self.kwargs['ticket_reference'],
            ticket_code=self.kwargs['ticket_code'],
        )

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super().get(request, *args, **kwargs)

    @cached_property
    def attendee_form(self):
        return AssignAttendeeForm(
            prefix='attendee',
            data=self.request.POST or None,
            instance=self.object,
        )

    @cached_property
    def get_consent(self):
        organizer = self.object.event.organizer
        return organizer.contacts.filter(email=self.object.email).first()

    @cached_property
    def consent_form(self):
        return AttendeeConsentForm(
            prefix='consent',
            data=self.request.POST or None,
            instance=self.get_consent,
            email=self.object.email,
        )

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'attendee': self.object,
            'attendee_form': self.attendee_form,
            'consent_form': self.consent_form,
        })
        return context

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()

        # Check if consent already exists which defines if consent entry will be
        # updated or if a new one will be created.
        consent = self.get_consent
        print(self.object.email, "self.object.email")

        # Validate forms
        forms = [
            self.attendee_form.is_valid(),
            self.consent_form.is_valid(),
        ]

        print(self.object.email, "self.object.email 2")

        if not all(forms):
            messages.error(request, _("Please correct the errors in the form."))
        else:
            self.object = self.attendee_form.save()
            if consent:
                consent.first_name = self.object.first_name
                consent.last_name = self.object.last_name
                consent.email = self.object.email
                consent.save(
                    update_fields=['email', 'first_name', 'last_name']
                )
                consent.events.add(self.object.event)
            else:
                consent_form = self.consent_form.save(commit=False)
                consent_form.email = self.object.email
                consent_form.first_name = self.object.first_name
                consent_form.last_name = self.object.last_name
                consent_form.organizer = self.object.event.organizer
                consent_form.save()
                consent_form.events.add(self.object.event)

标签: pythondjango

解决方案


这是预期的结果。is_valid() 正在检查以确保表单有效,即满足您在模型或表单的 clean 方法中规定的所有要求。它使用新数据更新对象,因此使用 print 2 语句,以便您在需要时保存对象。因此,如果您更改了电子邮件地址,并且表单中没有验证错误,那么当您提交表单时,该对象将根据您的 post 方法与新电子邮件一起保存。如果您没有调用 save 那么它仍然会在您的控制台中打印新电子邮件,但是当您检查数据库时它将是旧电子邮件。


推荐阅读