创建一个表单,供用户填写他们的姓名和电子邮件、电子邮件收件人和可选的注释
创建blog/forms.py
from django import forms
class EmailPostForm(forms.Form):
name = forms.CharField(max_length=25)
email = forms.EmailField()
to = forms.EmailField()
comments = forms.CharField(required=False,widget=forms.Textarea)
通过继承form基类创建了一个表单。Django使用不同的字段类型来验证字段。
每个字段类型都有一个默认的HTML小部件,name字段为CharField,使用<input type="text"> HTML标签呈现。
使用widget属性可以覆盖默认HTML部件。在comments字段中,使用Textarea部件将用<textarea>标签,而不是默认的<input>标签。
required将comments字段定义为可选字段。
表单字段 | Django 文档 | Django (djangoproject.com)
📌表单可以驻留在Django项目的任何地方。惯例是将它们放在每个应用程序的forms.py文件中。
创建一个视图,用于处理提交的数据并发送电子邮件
from .forms import EmailPostForm
from django.core.mail import send_mail
def post_share(request, post_id):
post = get_object_or_404(Post, id=post_id, status='published')
sent = False
if request.method == 'POST':
form = EmailPostForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{}({}) recommends you reading"{}"'.format(cd['name'],cd['email'],post.title)
message = 'Read"{}" at {}\n\n{}\'s comments:{}'.format(post.title,post_url,cd['name'],cd['comments'])
send_mail(subject,message,'admin@blog.com',[cd['to']])
sent = True
else:
form = EmailPostForm()
template = "blog/post/share.html"
context = {
'post':post,
'form':form,
'sent':sent,
}
return render(request, template,context)
📌 如果表单验证无效,cleaned_data仅包含表单字段。
由于要在电子邮件中包含指向该文章的链接,因此使用该文章的get_absolute_url()方法检索该文章的绝对路径,作为request.build_absolute_uri()的输入,构建一个完整的URL,包括HTTP和主机名。
使用经过验证的表单数据构建电子邮件的主题和消息体,最后将电子邮件发送到表单的to字段包含的电子邮件地址。
在应用的urls.py中为新视图添加一个URL路径
urlpatterns = [
# ...
path('<int:post_id>/share/',views.post_share, name='post_share'),
]
创建一个模版来显示表单
在创建表单、编程视图和添加URL模式之后,还缺少这个视图的模板。
在blog/templates/blog/post/目录新建一个文件,命名为share.html
{% extends "blog/base.html" %}
{% block title %}Share a post{% endblock %}
{% block content %}
{% if sent %}
<h1>E-mail successfully sent</h1>
<p>
"{{ post.title }}" was successfully sent to {{ form.cleaned_data.to
}}.
</p>
{% else %}
<h1>Share "{{ post.title }}" by e-mail</h1>
<form action="." method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Send e-mail">
</form>
{% endif %}
{% endblock %}
使用form.as_p方法会使用\<p>呈现段落,还可以使用as_ul将表单呈现为无序列表,或者使用as_table将表单呈现为HTML表格。
如果需要遍历每个字段,可以使用:
{% for field in form %}
<div>
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
在博客详情页把post_share的链接添加到模版
blog/post/detail.html
<p>
<a href='{% url "blog:post_share" post.id %}'>
Share this post
</a>
</p>