step:1创建验证时发送邮件的app
在apps目录下创建utils文件夹,并创建文件email_send.py
图片.png
setp:2编辑email_send.py
# _*_ encoding:utf-8 _*_
__author__ = 'luky'
__date__ = '2018/5/2 9:54'
from random import Random
# 导入django内置的send_mail函数,发送邮件
from django.core.mail import send_mail
# 调用users中models.py定义的EmailVerifyRecord函数
from users.models import EmailVerifyRecord
# 导入settings定义的邮件服务器
from mxonline.settings import EMAIL_FROM
# 随机生成字符串的函数
def random_str(randomlength=8):
str = '' #定义空串
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'#定义随机可选的字符串
length = len(chars) - 1 #
random = Random() #调用Random方法 随机生成数字
#根据生成的数字 到chars中去取对应的字符串,然后加在一起。
for i in range(randomlength):
str+=chars[random.randint(0, length)]
return str
# 创建邮箱认证的方法,调用EmailVerifyRecord函数中的字段和随机生成的字符串保存到数据库中,用于验证时的匹配
def send_register_email(email, send_type="register"):#send_type不能为0
email_record = EmailVerifyRecord()
code = random_str(16)
email_record.code = code
email_record.email = email
email_record.send_type = send_type
email_record.save()
# 定义好邮件的内容
email_title = ""
email_body = ""
# 通过判断send_type的值,来发送不通的邮件内容。
if send_type == "register":
email_title = "慕学在线网注册激活链接"
email_body = "请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/{0}".format(code)
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
if send_status:
pass
setp:3 在settings中设置邮件服务器的信息,在最下面添加相关配置
编辑 settings.py
# EMAIL_FROM 与EMAIL_HOST_USER要保持一致
EMAIL_HOST = "smtp.163.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "username@163.com"
EMAIL_HOST_PASSWORD = "password"
EMAIL_USE_TLS = False
EMAIL_FROM = "username@163.com"
setp:4在views增加发送邮件的调用
在上面增加函数的调用
#调用邮件验证的函数
from utils.email_send import send_register_email
修改ResgisterView类中的post方法,增加邮件发送的动作
def post(self, request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("email", "")
pass_word = request.POST.get("password", "")
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
user_profile.password = make_password(pass_word)
user_profile.save()
send_register_email(user_name, "register")
return render(request, "login.html")
else:
return render(request, "register.html")
setp5:邮箱注册功能验证
设置断点,debug启动
图片.png
登陆注册页面输入正确的信息
图片.png
然后查看pycharm 按F8 断点调试,可以通过截图看到验证通过
图片.png
查看数据库users_userprofile表,新创建的用户已入库
图片.png
登陆邮箱查看,已收到激活链接的邮件~~~
图片.png
step6:完善views 增加错误输出
修改views/py,在修改ResgisterView类中的post方法增加 else部分
else:
return render(request, "register.html", {"register_form":register_form})
修改register.html中的用户输入部分,增加错误输出代码和输入回填功能。
<div class="tab-form">
<form id="email_register_form" method="post" action="{% url 'resgister' %}" autocomplete="off">
<input type='hidden' name='csrfmiddlewaretoken' value='gTZljXgnpvxn0fKZ1XkWrM1PrCGSjiCZ' />
<!-- {% if register_form.errors.email %}errorput{% endif %}"将用户输入的错误信息显示出来 -->
<div class="form-group marb20 {% if register_form.errors.email %}errorput{% endif %}">
<label>邮 箱</label>
<!-- value="{{ register_form.email.value }}将用户上一次输入的内容回填进去 -->
<input type="text" id="id_email" name="email" value="{{ register_form.email.value }}" placeholder="请输入您的邮箱地址" />
</div>
<!-- {% if register_form.errors.password %}errorput{% endif %}"将用户输入的密码错误信息显示出来 -->
<div class="form-group marb8 {% if register_form.errors.password %}errorput{% endif %}">
<label>密 码</label>
<input type="password" id="id_password" name="password" value="{{ register_form.password.value }}" placeholder="请输入6-20位非中文字符密码" />
</div>
<div class="form-group marb8 captcha1 {% if register_form.errors.captcha %}errorput{% endif %}">
<label>验 证 码</label>
{{ register_form.captcha }}
</div>
<div class="error btns" id="jsEmailTips">{% for key,error in register_form.errors.items %}{{ error }}{% endfor %}{{ msg }}</div>
<div class="auto-box marb8">
</div>
<input class="btn btn-green" id="jsEmailRegBtn" type="submit" value="注册并登录" />
{% csrf_token %}
</form>
验证如下:
image.png
step7:邮箱激活
修改 view.py,ResgisterView类中的post方法,增加user_profile.is_active = False
if register_form.is_valid():
user_name = request.POST.get("email", "")
pass_word = request.POST.get("password", "")
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
# user_profile.is_active = False表明用户未激活
user_profile.is_active = False
user_profile.password = make_password(pass_word)
user_profile.save()
修改urls.py,增加激活码访问的格式active/,定义匹配active_code的字符串
from django.conf.urls import url, include
# from django.contrib import admin
from django.views.generic import TemplateView
import xadmin
from users.views import LoginView, ResgisterView,ActiveUserView
urlpatterns = [
url(r'^xadmin/', xadmin.site.urls),
url('^$', TemplateView.as_view(template_name="index.html"), name="index"),
url('^login/$', LoginView.as_view(), name="login"),
url('^register/$', ResgisterView.as_view(), name="resgister"),
url(r'^captcha/', include('captcha.urls')),
url(r'^active/(?P<active_code>.*)/$', ActiveUserView.as_view(), name="user_active"),
修改view.py,新增ActiveUserView类
class ActiveUserView(View):
def get(self, request, active_code):
pass
验证激活码能否获得到
先设置断点
image.png
再到邮箱查看收到的验证邮件
image.png
访问邮件中的地址,然后查看pycharm中的debug信息,可以匹配到active_code与邮件中的字符串一致。
image.png
我们已经能够获取active_code了,接下来修改views.py增加逻辑,查询匹配验证记录是否存在和用户是否激活以及相应的触发动作。
增加 EmailVerifyRecord的调用
from .models import UserProfile, EmailVerifyRecord
修改ActiveUserView类,判断用户的验证码记录,并根据结果修改数据库的值。
class ActiveUserView(View):
def get(self, request, active_code):
# 查询邮件中的验证码与code是否一致
all_records = EmailVerifyRecord.objects.filter(code=active_code)
if all_records:
for record in all_records:
email = record.email
user = UserProfile.objects.get(email=email)
user.is_active = True
user.save()
return render(request, "login.html")
修改LoginView类的post函数,增加用户是否激活的判断。
class LoginView(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
# 增加form组件对用户提交的表单进行预处理,验证参数是否正确
login_form = LoginForm(request.POST)
if login_form.is_valid():
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None:
#验证用户是否激活
if user.is_active:
login(request, user)
return render(request, "index.html")
else:
return render(request, "login.html", {"msg": "用户未激活!"})
else:
# 2{"msg":"用户名密码输入错误!"}定义数据库查询后验证的报错输。在login.html代码中加入
return render(request, "login.html", {"msg": "用户名密码输入错误!"})
else:
# 3{"login_form":login_form}定义form验证报错输。在login.html代码中加入
return render(request, "login.html", {"login_form":login_form})
此时查看数据库users_userprofile表中的is_active字段,查看kn_0933用户的值为0,表示未激活。
image.png
那么测试用上述的邮箱登陆,结果显示用户未激活。
image.png
然后我们访问一下邮件中验证的地址:http://127.0.0.1:8000/active/HEcXTVNYSkzKQWTC
此时可以看到数据库中的字段值已经变为1,表示已激活状态。
最后我们用邮箱登陆,一切OK~
image.png
#######################补充########################
增加注册时判断用户是否存在,以及激活验证失败的动作
step1:修改views.py,ResgisterView类的post方法,增加如下代码
if UserProfile.objects.filter(email=user_name):
return render(request, "register.html", {"register_form":register_form, "msg":"用户已存在"})
def post(self, request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("email", "")
# 判断用户的EMAIL是否已存在
if UserProfile.objects.filter(email=user_name):
return render(request, "register.html", {"register_form":register_form, "msg":"用户已存在"})
pass_word = request.POST.get("password", "")
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
# user_profile.is_active = False表明用户未激活
user_profile.is_active = False
user_profile.password = make_password(pass_word)
user_profile.save()
send_register_email(user_name, "register")
return render(request, "login.html")
else:
# {"register_form":register_form}定义form验证报错输。在register.html代码中加入
return render(request, "register.html", {"register_form":register_form})
验证:登陆已注册好的用户。
image.png
step2:发送激活链接时,检测用户不存在后的动作,增加链接失效页面
在template中新建链接失效页面active_fail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>链接失效<p>
</body>
</html>
修改views.py,ActiveUserView类增加如下代码
else:
return render(request, "avtive_fail.html")
class ActiveUserView(View):
def get(self, request, active_code):
# 查询邮件中的验证码与code是否一致
all_records = EmailVerifyRecord.objects.filter(code=active_code)
if all_records:
for record in all_records:
email = record.email
user = UserProfile.objects.get(email=email)
user.is_active = True
user.save()
else:
return render(request, "avtive_fail.html")
return render(request, "login.html")
验证:打开浏览器 输入http://127.0.0.1:8000/active/随机输入一些字符串
网友评论