在上一章中,我们创建了一个基础的博客应用,我们能在http://127.0.0.1:8000/blog/显示我们的博客。在这一章我们将尝试给博客系统添加一些高级的特性,比如通过email来分享帖子,添加评论,给帖子打上tag.

通过email分享帖子:

要通过email来分享帖子,需要我们创建一个表单来填写姓名,email,收件人。因此第一步就是通过django来创建表单。首先在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类的表单。我们就可以对页面上提交的数据进行验证。当表单提交从成功后必须创建一个新的视图来操作表单和发送email。编辑views.py文件,添加如下代码:

from .forms import EmailPostForm

def post_share(request,post_id):

post=get_object_or_404(Post,id=post_id,status='published')

if request.method == 'POST':

form=EmailPostForm(request.POST)

if form.is_valid():

cd=form.cleaned_data

#send email

else:

form=EmailPostForm()

return render(request,'post/share.html',{'post':post,'form':form})

在这个视图函数中,完成了如下的工作

1 定义post_share视图,参数为request和post_id

2   使用get_object_or_404快捷方法通过ID获取对应的帖子,并且确保每个帖子都是published状态

3 对提交的表单数据进行验证,如果验证通过则通过form.cleaned_data获取验证过的数据

接下来就要配置Django发送email:

首先,你需要有一个本地的SMTP服务或者通过在你项目的settings.py文件中添加以下设置去定义一个外部SMTP服务器的配置:

  • EMAIL_HOST: SMTP服务地址。默认本地。
  • EMAIL_POSR: SMATP服务端口,默认25。
  • EMAIL_HOST_USER: SMTP服务的用户名。
  • EMAIL_HOST_PASSWORD: SMTP服务的密码。
  • EMAIL_USE_TLS: 是否使用TLS加密连接。
  • EMAIL_USE_SSL: 是否使用隐式的SSL加密连接。

在settings.py中配置如下:

EMAIL_HOST = 'smtp.163.com'

EMAIL_HOST_USER = 'maple412@163.com'

EMAIL_HOST_PASSWORD = 'xxxx'

EMAIL_PORT = 25

EMAIL_USE_TLS = True

配置好了,我们来实际测试一下:打开shell功能

zhf@zhf-maple:~/py_prj/mysite$ python manage.py shell

Python 2.7.14 (default, Sep 23 2017, 22:06:14)

Type "copyright", "credits" or "license" for more information.

IPython 5.5.0 -- An enhanced Interactive Python.

?         -> Introduction and overview of IPython's features.

%quickref -> Quick reference.

help      -> Python's own help system.

object?   -> Details about 'object', use 'object??' for extra details.

In [3]: from django.core.mail import send_mail

In [4]: send_mail('Django email','This is email from django test','maple412@163.com',['179039149@qq.com'],fail_silently=False)

Out[4]: 1

send_mail()方法需要这些参数:邮件主题,内容,发送人以及一个收件人的列表。通过设置可选参数fail_silently=False,我们告诉这个方法如果email没有发送成功那么需要抛出一个异常。如果你看到输出是1,证明你的email发送成功了。

既然测试成功,那么我们把发送邮件的功能添加到试图函数中去

def post_share(request,post_id):

post=get_object_or_404(Post,id=post_id,status='published')

send=False

if request.method == 'POST':

form=EmailPostForm(request.POST)

if form.is_valid():

cd=form.cleaned_data

subject='{}({}) recommends you reading "{}"'.format(cd['name'],cd['email'],post.title)

message='Read "{}" at {}\n\n{}\'s comments'.format(post.title,cd['name'],cd['comments'])

send_mail(subject,message,'maple412@163.com',[cd['to']])

send=True

#send email

else:

form=EmailPostForm()

return render(request,'post/share.html',{'post':post,'form':form,'send':send})

在这里我们声明了一个sent变量并且当帖子被成功发送时赋予它True。当表单成功提交的时候,我们之后将在模板(template)中使用这个变量显示一条成功提示。

视图函数已经完成,最后要做的就是添加路由

url(r'^(?P<post_id>\d+)/share/$',views.post_share,name='post_share'),

视图和url都配置完了后,最后就剩下配置模板了

1 在post目录下创建一个share.html, 在该文件中添加如下代码:

{% extends "blog/base.html" %}

{% block title %}Share a post{% endblock %}

{% block content %}

{% if send %}

<h1>E-mail successfully sent</h1>

<p>

"{{ post.title }}" was successfully sent to {{ cd.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 %}

这里通过传入的send参数来判断邮件是否发送成功.如果发送成功,则显示发送的博客名称,发送人和接受人.

2在list.html中添加如下代码,也就是添加一个分享博客的url链接.这个url正好的组成是blog+post.id+share,正好对应url(r'^(?P<post_id>\d+)/share/$',views.post_share,name='post_share')这个URL

<a href="/blog/{{ p.id }}/share">

分享这篇博客

</a>

</p>

现在来进行测试.进入如下界面

点击分享这篇博客,在下面界面中填写信息

发送成功后跳转到发送成功的界面

最新文章

  1. SignalR入门之基本介绍
  2. FormsAuthentication身份认证源代码
  3. python 过滤出某后缀名文件
  4. C#基础学习文章导航
  5. codevs3872 邮递员送信(SPFA)
  6. unix环境C编程之日期时间转换
  7. Objective-C特点
  8. Qt5中生成和使用静态库
  9. [Windows编程] 使用AttachThreadInput 来捕捉其它窗口的键盘输入
  10. C++中数字与字符串之间的转换(使用CString.Format或者sprintf)
  11. linux ifconfig命令使用详解
  12. git fetch, merge, pull, push需要注意的地方(转)
  13. ROS机器人程序设计(原书第2版)补充资料 (零) 源代码、资料和印刷错误修订等 2017年01月01日更新
  14. CentOS 6 安装HBase集群教程
  15. PrismCDN 网络的架构解析,以及低延迟、低成本的奥秘
  16. 爬虫之进阶 基于twisted实现自制简易scrapy框架(便于对scrapy源码的理解)
  17. 《转》完美解决微信video视频隐藏控件和内联播放问题
  18. flink1.7 checkpoint源码分析
  19. Caused by: java.lang.IllegalStateException: commit already called
  20. Oracle 小技巧

热门文章

  1. 获得Oracle中刚插入的数据的ID(for produce)
  2. 单端IO标准
  3. Redis value的5种类型及常见操作
  4. Python unittest excel数据驱动 写入
  5. struts1-mapping.getInputForward()与mapping.getInput
  6. 使用Eclipse中遇到的问题
  7. apache server和tomcat集群配置二:垂直负载
  8. activity状态保存的bundl对象存放位置的思考
  9. 第4章_Java仿微信全栈高性能后台+移动客户端
  10. day36-hibernate检索和优化