step:1創(chuàng)建驗(yàn)證時(shí)發(fā)送郵件的app
在apps目錄下創(chuàng)建utils文件夾,并創(chuàng)建文件email_send.py
setp:2編輯email_send.py
# _*_ encoding:utf-8 _*_
__author__ = 'luky'
__date__ = '2018/5/2 9:54'
from random import Random
# 導(dǎo)入django內(nèi)置的send_mail函數(shù),發(fā)送郵件
from django.core.mail import send_mail
# 調(diào)用users中models.py定義的EmailVerifyRecord函數(shù)
from users.models import EmailVerifyRecord
# 導(dǎo)入settings定義的郵件服務(wù)器
from mxonline.settings import EMAIL_FROM
# 隨機(jī)生成字符串的函數(shù)
def random_str(randomlength=8):
str = '' #定義空串
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'#定義隨機(jī)可選的字符串
length = len(chars) - 1 #
random = Random() #調(diào)用Random方法 隨機(jī)生成數(shù)字
#根據(jù)生成的數(shù)字 到chars中去取對(duì)應(yīng)的字符串,然后加在一起。
for i in range(randomlength):
str+=chars[random.randint(0, length)]
return str
# 創(chuàng)建郵箱認(rèn)證的方法灰蛙,調(diào)用EmailVerifyRecord函數(shù)中的字段和隨機(jī)生成的字符串保存到數(shù)據(jù)庫中,用于驗(yàn)證時(shí)的匹配
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()
# 定義好郵件的內(nèi)容
email_title = ""
email_body = ""
# 通過判斷send_type的值,來發(fā)送不通的郵件內(nèi)容巧还。
if send_type == "register":
email_title = "慕學(xué)在線網(wǎng)注冊(cè)激活鏈接"
email_body = "請(qǐng)點(diǎn)擊下面的鏈接激活你的賬號(hào): 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中設(shè)置郵件服務(wù)器的信息,在最下面添加相關(guān)配置
編輯 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增加發(fā)送郵件的調(diào)用
在上面增加函數(shù)的調(diào)用
#調(diào)用郵件驗(yàn)證的函數(shù)
from utils.email_send import send_register_email
修改ResgisterView類中的post方法,增加郵件發(fā)送的動(dòng)作
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:郵箱注冊(cè)功能驗(yàn)證
設(shè)置斷點(diǎn)坊秸,debug啟動(dòng)
登陸注冊(cè)頁面輸入正確的信息
然后查看pycharm 按F8 斷點(diǎn)調(diào)試麸祷,可以通過截圖看到驗(yàn)證通過
查看數(shù)據(jù)庫users_userprofile表,新創(chuàng)建的用戶已入庫
登陸郵箱查看褒搔,已收到激活鏈接的郵件~~~
step6:完善views 增加錯(cuò)誤輸出
修改views/py阶牍,在修改ResgisterView類中的post方法增加 else部分
else:
return render(request, "register.html", {"register_form":register_form})
修改register.html中的用戶輸入部分,增加錯(cuò)誤輸出代碼和輸入回填功能星瘾。
<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 %}"將用戶輸入的錯(cuò)誤信息顯示出來 -->
<div class="form-group marb20 {% if register_form.errors.email %}errorput{% endif %}">
<label>郵 箱</label>
<!-- value="{{ register_form.email.value }}將用戶上一次輸入的內(nèi)容回填進(jìn)去 -->
<input type="text" id="id_email" name="email" value="{{ register_form.email.value }}" placeholder="請(qǐng)輸入您的郵箱地址" />
</div>
<!-- {% if register_form.errors.password %}errorput{% endif %}"將用戶輸入的密碼錯(cuò)誤信息顯示出來 -->
<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="請(qǐng)輸入6-20位非中文字符密碼" />
</div>
<div class="form-group marb8 captcha1 {% if register_form.errors.captcha %}errorput{% endif %}">
<label>驗(yàn) 證 碼</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="注冊(cè)并登錄" />
{% csrf_token %}
</form>
驗(yàn)證如下:
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
驗(yàn)證激活碼能否獲得到
先設(shè)置斷點(diǎn)
再到郵箱查看收到的驗(yàn)證郵件
訪問郵件中的地址融求,然后查看pycharm中的debug信息,可以匹配到active_code與郵件中的字符串一致算撮。
我們已經(jīng)能夠獲取active_code了生宛,接下來修改views.py增加邏輯,查詢匹配驗(yàn)證記錄是否存在和用戶是否激活以及相應(yīng)的觸發(fā)動(dòng)作肮柜。
增加 EmailVerifyRecord的調(diào)用
from .models import UserProfile, EmailVerifyRecord
修改ActiveUserView類陷舅,判斷用戶的驗(yàn)證碼記錄,并根據(jù)結(jié)果修改數(shù)據(jù)庫的值审洞。
class ActiveUserView(View):
def get(self, request, active_code):
# 查詢郵件中的驗(yàn)證碼與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函數(shù)莱睁,增加用戶是否激活的判斷待讳。
class LoginView(View):
def get(self, request):
return render(request, "login.html", {})
def post(self, request):
# 增加form組件對(duì)用戶提交的表單進(jìn)行預(yù)處理,驗(yàn)證參數(shù)是否正確
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:
#驗(yàn)證用戶是否激活
if user.is_active:
login(request, user)
return render(request, "index.html")
else:
return render(request, "login.html", {"msg": "用戶未激活仰剿!"})
else:
# 2{"msg":"用戶名密碼輸入錯(cuò)誤创淡!"}定義數(shù)據(jù)庫查詢后驗(yàn)證的報(bào)錯(cuò)輸。在login.html代碼中加入
return render(request, "login.html", {"msg": "用戶名密碼輸入錯(cuò)誤南吮!"})
else:
# 3{"login_form":login_form}定義form驗(yàn)證報(bào)錯(cuò)輸琳彩。在login.html代碼中加入
return render(request, "login.html", {"login_form":login_form})
此時(shí)查看數(shù)據(jù)庫users_userprofile表中的is_active字段,查看kn_0933用戶的值為0部凑,表示未激活露乏。
那么測(cè)試用上述的郵箱登陸,結(jié)果顯示用戶未激活涂邀。
然后我們?cè)L問一下郵件中驗(yàn)證的地址:http://127.0.0.1:8000/active/HEcXTVNYSkzKQWTC
此時(shí)可以看到數(shù)據(jù)庫中的字段值已經(jīng)變?yōu)?瘟仿,表示已激活狀態(tài)。
最后我們用郵箱登陸比勉,一切OK~
#######################補(bǔ)充########################
增加注冊(cè)時(shí)判斷用戶是否存在劳较,以及激活驗(yàn)證失敗的動(dòng)作
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驗(yàn)證報(bào)錯(cuò)輸浩聋。在register.html代碼中加入
return render(request, "register.html", {"register_form":register_form})
驗(yàn)證:登陸已注冊(cè)好的用戶兴想。
step2:發(fā)送激活鏈接時(shí),檢測(cè)用戶不存在后的動(dòng)作赡勘,增加鏈接失效頁面
在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):
# 查詢郵件中的驗(yàn)證碼與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")
驗(yàn)證:打開瀏覽器 輸入http://127.0.0.1:8000/active/隨機(jī)輸入一些字符串