django2实战5.创建表单及发送邮件

继上篇 django2实战4.创建文章列表页和详情页

本篇要实现这样的功能:在文章详情页增加分享文章的入口,点击后跳到分享页面,提交要发送的email地址,程序将发送邮件到相应邮箱,邮件内容是文章的链接地址。

测试邮件发送

django自带了发送邮件的功能,只需要简单的配置即可,以163邮件服务器为例:

mysite/mysite/settings.py

新增邮件服务器配置:

EMAIL_HOST = 'smtp.163.com'
EMAIL_HOST_USER = '******@163.com' # 填写你的邮件地址
EMAIL_HOST_PASSWORD = '******' # 密码
EMAIL_PORT = 25
EMAIL_USE_TLS = True

在交互环境测试发送邮件

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

In [3]: send_mail('Django mail', '通过Django发送的邮件', '发送方的邮件', ['接收方邮件'], fail_silently
   ...: =False)
Out[3]: 1
邮件发送

创建表单页面

django内置了生成表单的功能,但其默认的样式太难看了,我们结合bootstrap对表单样式进行改造

新建 mysite/blog/forms.py

from django import forms


class EmailPostForm(forms.Form):
    name = forms.CharField(label='用户名', max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
    email = forms.EmailField(label='发送方邮件', widget=forms.EmailInput(attrs={'class': 'form-control'}))
    to = forms.EmailField(label='接收方邮件', widget=forms.EmailInput(attrs={'class': 'form-control'}))
    comments = forms.CharField(label='推荐语', required=False,
                               widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3}))

django会根据此表单模型生成相应的表单元素,并对表单提交数据进行验证

业务逻辑搭建

分享页面的由文章详情页跳转而来,且分享的是具体的某篇文章,所以必须携带文章id

据此设定分享页面的url为:http://127.0.0.1:8000/blog/id/share/

url配置

mysite/blog/urls.py

path('<int:post_id>/share/', views.post_share, name='post_share')

view层逻辑

url配置文件指定了访问入口,在view中新增分享文章的逻辑:

# ...
from .forms import EmailPostForm
from django.core.mail import send_mail
# ...
# 文章分享
def post_share(request, post_id):
    # 根据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 = '{} ({}) 推荐你阅读"{}"'.format(cd['name'], cd['email'], post.title)
            message = '查看"{}" {}\n\n{} 的评论:{}'.format(post.title, post_url, cd['name'], cd['comments'])
            send_mail(subject, message, '******@163.com', [cd['to']])  # 替换为你自己的163邮箱
            sent = True
    else:
        form = EmailPostForm()
    return render(request, 'blog/post/share.html', {'post': post,
                                                    'form': form,
                                                    'sent': sent})

当http请求是post方式时,post_share接收表单数据并发送邮件;否则便是展示表单样式

由于指定的html模板是blog/post/share.html, 因此需要创建此文件

新建分享页面模板

mysite/blog/templates/blog/post/share.html

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

{% block title %}分享文章{% endblock %}

{% block content %}
  {% if sent %}
    <h3 class="text-success">邮件发送成功</h3>
    <p>
      "{{ post.title }}" 已经成功发送到 {{ form.cleaned_data.to }}.
    </p>
  {% else %}
    <h3 class="text-info">向你的朋友推荐阅读 "{{ post.title }}"</h3>
    <form action="." method="post">
        {% csrf_token %}
        {% for field in form %}
        <div class="form-group has-errors text-danger small">
            {{field.errors}}
        </div>
        <div class="form-group has-errors text-danger small">
        </div>
        <div class="form-group">
            <label for="">{{ field.label }}:</label>
            {{field}}
        </div>
        {% endfor %}
      <input type="submit" value="发送邮件">
    </form>
  {% endif %}
{% endblock %}

详情页添加分享入口

在文章详情页新增跳转至分享页面的入口,携带文章id

mysite/blog/templates/blog/post/detail.html

{% block content %}
    <!-- ... -->
    <div class="alert alert-success share">
        <a href="{% url "blog:post_share" post.id %}" class="text-success">推荐此文</a>
    </div>
{% endblock %}

调整样式

mysite/blog/static/css/blog.css

div.share {
    margin-top: 2%;
}

结果展示

http://127.0.0.1:8000/blog/2018/9/7/jiang-xue

推荐入口

分享页面,提交表单

表单提交

邮件发送成功的提示页

邮件发送成功

查看邮件

邮件内容

下一节将讲解如何搭建文章评价系统。如果你感兴趣,请关注我的django2实战文集

如果觉得本文对你有所帮助,点个赞,或者赏杯咖啡钱,你的认可对我很重要

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容