我需要一些电子邮件表单,我试试这个:
views.py
def send_email(request):
if request.method != 'POST':
form = EmailForm()
return render_to_response('mail_form.html', {'email_form': form})
form = EmailForm(request.POST, request.FILES)
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
email = form.cleaned_data['email']
attach = request.FILES['attach']
try:
mail = EmailMessage(subject, message, settings.EMAIL_HOST_USER, [email])
mail.attach(attach.name, attach.read(), attach.content_type)
mail.send()
return render(request, 'mail_form.html', {'message': 'Sent email to %s'%email})
except:
return render(request, 'mail_form.html', {'message': 'Either the attachment is too big or corrupt'})
return render(request, 'mail_form.html', {'message': 'Unable to send email. Please try again later'})
forms.py
class EmailForm(forms.Form):
email = forms.EmailField()
subject = forms.CharField(max_length=100)
attach = forms.Field(widget=forms.FileInput)
message = forms.CharField(widget = forms.Textarea)
mail_form.html
...
{{message}}
<form method="post" action="">
{% csrf_token %}
{{ email_form.as_p }}
<input type ="submit" name = "send" value = "Send"/>
</form>
...
但我经常遇到错误403.我尝试了网络上的不同解决方案,但没有任何帮助。我做错了什么?我理解views.py中的csrf有问题,但不明白具体问题在哪里。
答案 0 :(得分:1)
您的问题是render_to_reponse
。它没有你可以添加它的上下文实例,但render
为你处理这个,所以为什么不改为它。您也可以重新构建视图以使其更清洁。
以下是一个例子。
def send_email(request):
if request.method == 'POST':
form = EmailForm(request.POST, request.FILES)
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
email = form.cleaned_data['email']
attach = request.FILES['attach']
try:
mail = EmailMessage(subject, message, settings.EMAIL_HOST_USER, [email])
mail.attach(attach.name, attach.read(), attach.content_type)
mail.send()
messages.succes(request, 'Sent an email to %s' % email)
except:
messages.error(request, 'Either the attachment is too big or corrupt')
else:
form = EmailForm()
messages.info(request, "Send an email!")
return render(request, 'mail_form.html', {'email_form': form})
然后,您可以在模板中使用{% if messages %}
向用户显示您的消息/通过它们进行迭代并显示。
messages
此处来自django.contrib
,因此您需要from django.contrib import messages
答案 1 :(得分:0)
render_to_response
django.shortcuts
render_to_response
context_instance = RequestContext(request)
这必须使用csrf令牌解决您的问题或阅读https://docs.djangoproject.com/ja/1.9/ref/csrf/
答案 2 :(得分:0)
只需像这样修改你的view.py
from django.shortcuts import render
from django.template import RequestContext
def send_email(request):
if request.method != 'POST':
form = forms.EmailForm()
return render_to_response('mail_form.html', {'email_form': form}, context_instance=RequestContext(request))
......
......
答案 3 :(得分:0)
你使用的是什么版本的django?
嗯,显然你在部分代码中使用了render()
。问题出在您的GET代码中 - 您正在使用render_to_response()
:
if request.method != 'POST':
form = EmailForm()
return render_to_response('mail_form.html', {'email_form': form})
而是使用render():
return render(request, 'mail_form.html', {'email_form': form} )
请参阅example in the Django docs。
您需要这样做的原因是因为您需要使用csrf令牌:
在表单中插入csrf标记。
在请求/响应的标头中包含csrf标记作为cookie。
render()
完成#2,但render_to_response()
没有 - 除非你明确告诉它,你没有。无论如何,django 1.9 docs州:
<强> render_to_response()这个强>
此函数在引入render()之前有效 同样地,除了它没有使请求可用 响应。 不推荐使用 ,可能会弃用 将来