适当的联系表格技术?

时间:2011-03-10 18:28:13

标签: django

我在shantiyoga.ca/contact

处有一份联系表格

使用视图

def contact(request):

    template = 'contact.html'

    form = ContactForm(request.POST or None)    
    if form.is_valid(): # All validation rules pass

        subject = form.cleaned_data['subject']
        message = "%s\n\n%s" % (form.cleaned_data['message'], form.cleaned_data['sender'])
        cc_myself = form.cleaned_data['cc_myself']

        recipients = ['contact@shantiyoga.ca']

        sender = form.cleaned_data['sender']
        if cc_myself:
            recipients.append(sender)

        headers = {'Reply-To': form.cleaned_data['sender']}  

        from django.core.mail import send_mail
        send_mail(subject,message,sender,recipients,headers)

        return redirect('/thanks/')

    return render_to_response(template, {'form': form, 'current':'contact'}, context_instance=RequestContext(request))

哪个效果很好。我对Django并不是非常复杂,而且我的Python技能也不太适合鼻烟,所以如果我以基本的方式逐步完成这一点,请耐心等待。

我想澄清一下,表单收件人(contact@shantiyoga.ca)无法从电子邮件字段的值(用户输入)中接收联系表单。它将始终通过我的settings.py中经过身份验证的电子邮件发送,此时这是我的个人电子邮件?

用户填写联系表格并点击提交,电子邮件将从我的个人电子邮件发送至contact@shantiyoga.ca,如果用户决定自行提交,则会向他们发送电子邮件副本,我的个人电子邮件

这不是理想的,我应该为我的settings.py创建一个类似contactform@shantiyoga.ca的电子邮件来发送电子邮件吗?

此外,headers = {'Reply-To': form.cleaned_data['sender']}似乎没有做任何事情,我似乎无法找到描述其正确用法的文档,是否有人使用此技术取得了成功?

感谢您的时间, 诺亚

2 个答案:

答案 0 :(得分:0)

  

我想澄清一下,表单收件人(contact@shantiyoga.ca)无法从电子邮件字段的值(用户输入)中接收联系表单。它将始终通过我的settings.py中经过身份验证的电子邮件发送,此时这是我的个人电子邮件?

您是将电子邮件的发件人设置为sender但是使用EMAIL_HOST,是吗?如果是这种情况,请注意您的SMTP帐户将允许您从域以外的用户发送电子邮件。通常情况下,如果您在该服务器上拥有经过身份验证的帐户,则可以将From:字段设置为您喜欢的任何字段。

简而言之,此电子邮件会显示在您的收件箱中,似乎来自sender变量。所以当你点击回复时,你就可以给他们发回电子邮件,这就是我想你想要的。但是,它将使用您提供其身份验证详细信息的SMTP服务器发送。能够发送电子邮件(SMTP)和能够接收电子邮件之间存在脱节,我认为这让您感到困惑。

我从来没有尝试过,但是为了添加额外的标头我相信你需要使用EmailMessage对象。根据文档,你会:

e = EmailMessage(headers={'Reply-To':...
e.send()

小心这样做;具体而言,be careful to strip out newlines in the reply to field。我不知道默认的clean方法是否会这样做。

最后,你的django / python没有太大问题。通过意识,我唯一要说的就是不要使用它:

return redirect('/thanks/')

但是:

return HttpResponseRedirect(reverse('myapp.views.method',args=tuple,kwargs=dict))

这使您无法将URL硬编码到应用程序中。 reverse方法会从urls.py为您查找它们,因此您可以移动应用程序/更改网址,它仍然可以使用。

答案 1 :(得分:0)

以下是来自django documentationsend_mail的签名:

send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)

正如您所看到的,它没有headers参数。

您需要直接使用EmailMessage对象。

从视图中删除电子邮件格式也很不错。我会写一些更像这样的东西:

from django.core.mail.message import EmailMessage
from django.conf import settings

class ContactsEmailMessage(EmailMessage):
    def __init__(self, sender, subject, message, cc_myself):
        super(ContactEmailMessage, self).__init__(
            subject=subject,
            body=self._get_message(self, sender, message),
            from=settings.DEFAULT_FROM_EMAIL,
            to=settings.CONTACT_RECIPIENTS,
            headers=self._get_headers(sender),
            cc=(sender, ) if cc_myself else None
        )

    def _format_message(self, sender, message):
        return "%s\n\n%s" % (sender, message)

    def _get_headers(self, sender):
        return {
            'reply-to': sender
        }

现在您可以编写简洁易读的视图:

from myproject.mail.message import ContactsEmailMessage, BadHeaderError
from django.core.exceptions import SuspiciousOperation

def contact(request):
    ...
    form = ContactForm(request.POST or None)    
    if form.is_valid(): # All validation rules pass
        try:
            message = ContactsEmailMessage(**form.cleaned_data)
            message.send()
        except BadHeaderError:
            # django will raise this error if user will try to pass suspicious new-line
            # characters to "sender" or other fields. This is safe-guard from
            # header injections
            raise SuspiciousOperation()

        return redirect('/thanks/')
    ...