Django FormView method 'form_valid()' not working when I specify html form action

278 Views Asked by At

I'm trying to send this form data by POST. When I click on submit it redirects me to the <form action="{% url 'create-checkout-session' %}" specified but I never get the email. If I delete the <action="" it sends the data by email but of course I'm not getting redirected to the url I want. The thing is that this url is not something I can hardcode since It's generated by Stripe payments and for each request it's a new one, so the success_url of the FormView is not something I can use.

The thing I want to achieve is to get redirected to the form action but at the same time get the form data by email.

This is the form.

<form action="{% url 'create-checkout-session' %}" method="POST">
    {{form.name}}
    {{form.surname}}
<button type="submit" class="btn btn-success">
    Card Payment
</button>

And I'm handling it this way in the view.

class checkoutView(UserPassesTestMixin, FormView):
    template_name = 'store/checkout.html'
    form_class = userInfoForm
    success_url = reverse_lazy('create-checkout-session')

    def form_valid(self, form):
        subject = 'New message from: ' + form.cleaned_data['email']
        message = form.cleaned_data['name']
        recipient_list = settings.EMAIL_HOST_USER
        connection = settings.EMAIL_HOST_USER,
        send_mail(subject, message, recipient_list, connection)
        return super().form_valid(form)
1

There are 1 best solutions below

5
willeM_ Van Onsem On

You made some errors when you send the email. You use settings.EMAIL_HOST_USER as recipient_list, but this should be a list of recipients, not the email address from which you want to send items. The recipient_list is thus likely a singleton list with self.request.user as item. This should also be the fourth parameter of send_mail, not the third. It is also possible that you should use form.cleaned_data['email'] instead if that is the receiver that you want to send an email.

For the connection, we can make use of None to work with the DEFAULT_FROM_EMAIL setting, so we can send an email with:

class checkoutView(UserPassesTestMixin, FormView):
    template_name = 'store/checkout.html'
    form_class = userInfoForm
    success_url = reverse_lazy('create-checkout-session')

    def form_valid(self, form):
        subject = 'New message from: ' + form.cleaned_data['email']
        message = form.cleaned_data['name']
        recipient_list = [request.user.email]
        send_mail(subject, message, None, recipient_list)
        return super().form_valid(form)