1

I need to send an email after user submits a form on my page (this is still in development, but it'll be in production soon).

I've read this other answer but after my form is submitted I'm not reciving any email (I've used my personal email as the sender and the receiver, for testing).

What I need to modify?

PLUS: How to send images on emails? Any tutorial on this? I need to send professional emails after form submition.

settings.py

EMAIL_HOST = 'smtp.gmail.com'  # since you are using a gmail account
EMAIL_PORT = 587  # Gmail SMTP port for TLS
EMAIL_USE_TLS = True

EMAIL_HOST_USER = 'oma.oma@gmail.com' #Not my actual email
EMAIL_HOST_PASSWORD = 'MyPassword' #Not my actual password

views.py:

# here we are going to use CreateView to save the Third step ModelForm
class StepThreeView(CreateView):
    form_class = StepThreeForm
    template_name = 'main_app/step-three.html'
    success_url = '/'

    def form_valid(self, form):
        form.instance.tamanios = self.request.session.get('tamanios')  # get tamanios from session
        form.instance.cantidades = self.request.session.get('cantidades')  # get cantidades from session
        del self.request.session['cantidades']  # delete cantidades value from session
        del self.request.session['tamanios']  # delete tamanios value from session
        self.request.session.modified = True
        return super(StepThreeView, self).form_valid(form)

form.py:

from django.core.mail import send_mail

class StepThreeForm(forms.ModelForm):
    instrucciones = forms.CharField(widget=forms.Textarea)
    class Meta:
        model = TamaniosCantidades
        fields = ('imagenes', 'instrucciones')

    def __init__(self, *args, **kwargs):
        super(StepThreeForm, self).__init__(*args, **kwargs)
        self.fields['instrucciones'].required = False

    def send_email(self):
        send_mail('Django Test', 'My message', 'oma.oma@gmail.com',
                  ['oma.oma@gmail.com'], fail_silently=False)
Omar Gonzales
  • 3,806
  • 10
  • 56
  • 120

1 Answers1

3

You can override the save method like this in your Last Form:

 class StepThreeForm(forms.ModelForm):
      def save(self, commit=True):
          instance = super(StepThreeForm, self).save(commit=commit)
          self.send_email()
          return instance

       def send_email(self):
           image = self.cleaned_data.get('imagenes', None)
           msg = EmailMessage(
              'Hello',
              'Body goes here',
              'from@example.com',
              ['to1@example.com', 'to2@example.com'],
              headers={'Message-ID': 'foo'},
           )

           msg.content_subtype = "html"

           if image:
             mime_image = MIMEImage(image.read())
             mime_image.add_header('Content-ID', '<image>')
             msg.attach(mime_image)
           msg.send()

You can check this SO Answer for more details on how to send image from Django

ruddra
  • 50,746
  • 7
  • 78
  • 101
  • There are unsolve references in your `send_email` method: `EmailMessage` and `MIMEImage`. So tried only updating the save method and got this error: `'NoneType' object has no attribute '__dict__'` – Omar Gonzales Nov 22 '18 at 03:52
  • @OmarGonzales updated my answer, missed the return statement from save method – ruddra Nov 22 '18 at 03:54
  • tried the updated answer, but getting: `Could not guess image MIME subtype` even I'm not attaching any image. – Omar Gonzales Nov 22 '18 at 03:55
  • instead of `msg.attach(mime_image)`, maybe you can use `msg.attach_file(obj.imagenes.path)` and pass this obj in the `send_email` method like `self.send_email(obj=instance)`. For documentation, please see here: https://docs.djangoproject.com/en/2.1/topics/email/#emailmessage-objects . Update the method signature as well `def send_email(self, obj)` :) – ruddra Nov 22 '18 at 04:00