【问题标题】:Cannot get send_mail to work in Django 2.3. No error message. No log message indicating email is sent or not sent无法让 send_mail 在 Django 2.3 中工作。没有错误信息。没有指示电子邮件已发送或未发送的日志消息
【发布时间】:2019-11-20 09:14:54
【问题描述】:

所以我一直在互联网上搜索,试图让我的代码正常工作,我觉得我已经阅读了关于这个问题的每一篇文章,但仍然不明白为什么我无法让我的表单向我发送电子邮件.我创建了一个基于类的视图,它继承了 FormView 并编写了一个方法,该方法应该在有后请求时向我发送电子邮件。对于我的生活,我无法让它工作。

对于那些在同一条船上的人,这是一篇看起来很有希望的帖子,所以即使它对我没有帮助,也希望它能帮助你:

Django sending email

我的views.py:(两个电子邮件地址相同。它应该模拟我向自己发送电子邮件。)

class CandRegisterView(FormView):
    template_name = 'website/candidate_register.html'
    form_class = UploadResumeForm
    def send_email(self, request):
        if request.method == 'POST':
            send_mail('Test', 'This is a test', 'myemail@gmail.com', ['myemail@gmail.com'], fail_silently=False)

我的表单.py:

from django import forms

class UploadResumeForm(forms.Form):
    first_name = forms.CharField(
        widget=forms.TextInput(
            attrs={
            'type':'text',
            'class': 'form-control',
            'placeholder': 'First Name',
            }), 
        required=True)

我的 settings.py (变量存储在 .env 文件中,我使用 python 解耦来添加它们而不暴露 github 上的信息。但这些是它们的关联值)

EMAIL_USE_TLS=True
EMAIL_USE_SSL=False
EMAIL_HOST=smtp.gmail.com
EMAIL_HOST_USER=myemail@gmail.com
EMAIL_HOST_PASSWORD=***************
EMAIL_PORT=587
EMAIL_BACKEND='django.core.mail.backends.smtp.EmailBackend'
DEFAULT_FROM_EMAIL='myemail@gmail.com'
SERVER_EMAIL='myemail@gmail.com

urls.py:

from django.urls import path, re_path
from .views import CandRegisterView

re_path(r'^candidate-register/$', CandRegisterView.as_view(success_url="/candidate-register/"), name='cand_register'),

candidate_register.html:

<form method= "post" action="" accept-charset="UTF-8" role="form">
                {% csrf_token %}

                <fieldset>
                  <div class="form-group">
                    <div class="input-group input-group-lg">
                      <span class="input-group-addon"><i class="fa fa-fw fa-user"></i></span>
                      {{form.first_name}}
                      <!-- <input type="text"  class="form-control" placeholder="First Name" name={{form.first_name}}> -->
                    </div>
                  </div>
                  <input class="btn btn-lg btn-primary btn-block" type="submit" value="Send Email">
                </fieldset>
              </form>

这是我在单击“提交”按钮后从控制台获得的信息。:

[10/Jul/2019 13:19:21] "POST /candidate-register/ HTTP/1.1" 302 0
[10/Jul/2019 13:19:22] "GET /candidate-register/ HTTP/1.1" 200 16782
[10/Jul/2019 13:19:22] "GET /candidate-register/ HTTP/1.1" 200 16782

我希望它能够做的就是立即向我发送此人的名字。后来我希望他们能够向我发送一份包含他们简历的文件,但我认为我会从简单开始并使其变得更复杂,因为包括其他领域,但我什至无法让它发挥作用。任何帮助或提示将不胜感激。似乎发布请求正在发生,但未发送电子邮件。我还尝试在 python manage.py shell 中使用 send_mail 函数,它显示了一个看起来很有希望的响应(日志显示了电子邮件的样子。)但它没有向我的帐户发送电子邮件。

【问题讨论】:

  • 所以我部分地解决了这个问题。我遇到了这个堆栈溢出答案,它与使用自己的密码设置邮件应用程序有关。 stackoverflow.com/questions/6914687/django-sending-email
  • 话虽如此,我仍然不明白为什么我的代码没有触发电子邮件。我可以从 shell 中做到这一点,但不能从我的代码中做到这一点。

标签: django python-3.x forms email


【解决方案1】:

在您的表单类中,您需要定义一个可以在 form_valid 之后调用的 send_mail 函数。比如:

from django.core.mail import EmailMessage as email_msg


class UploadResume(forms.Form):
    first_name = forms.CharField()
    last_name = forms.CharField()
    email = forms.EmailField()
    resume_file = forms.FileField()

    class Meta:
        title = 'Resume Upload'

    def send_message(self, email, first_name, last_name, file):
        '''
        This function will be used to create an email object that will then be \
transmitted via a connection call.  This function takes in arguments that will \
be provided by the corresponding CBV's form_valid function.
        '''
        email_obj = email_msg(
            subject=f'Resumed Uploaded by {first_name} {last_name}!',
            body = 'You received a resume upload from {first_name} {last_name} \
                    at {email}.  Please follow-up.  \nThank you,\nYour Platform'
            from_email=email,
            to=['myemail@gmail.com'],
            reply_to= ['myemail@gmail.com']
            )
        # after creating the email object with the cleaned data generated from
        # the form fields, we will attach the resume contents to the object,
        # then submit it via SMTP settings from the settings.py file.

        attach_name = file.name
        try:
            attach_content = file.open().read()
        except Exception:
            attach_content = file.getvalue()
        attach_mimetype = mimetypes.guess_type(attach_name)[0]
        email_obj.attach(attach_name, attach_content, attach_mimetype)
        try:
            email_obj.send()
        except Exception as e:
            print(type(e), e.args, e)

从这里,您可以覆盖 CBV 中的 form_valid 函数,使用 form.cleaned_data.get(insert_arg_here) 函数提取相关参数。

如何做到这一点的一个例子可以是以下方式:

class CandRegisterView(FormView):
    template_name = 'website/candidate_register.html'
    form_class = UploadResumeForm

    def form_valid(self, form):
        if form.is_valid:
            email_addr = form.cleaned_data.get('email')
            first_name = form.cleaned_data.get('first_name')
            last_name = form.cleaned_data.get('last_name')
            file = form.cleaned_data.get('resume_file')
            form.send_message(email_addr, first_name, last_name, file)
        else:
            return form.errors

刚刚注意到这一点:当您在 HTML 中制作表单标签时,请确保标签中出现 enctype="multipart/form-data"

【讨论】:

  • 这很棒。它仍然不起作用,但这肯定有助于清理我收到的电子邮件。 “覆盖 form_valid 函数”到底是什么意思?
  • 我更新了我的答案以更好地回答这个问题。我认为我的示例基本上可以复制+粘贴到您的文件中。本质上,一般的FormView都有一个特定的表单验证功能,在管理表单数据的时候会执行,为了实现特定的功能(比如发送邮件),那么最好取form.is_valid()获取后生成的清理后的数据调用。
猜你喜欢
  • 1970-01-01
  • 2020-04-03
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2020-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多