1. 配置html等静态文件
a. 将project中的register.html copy至templates下
b. 修改静态文件路径
之前做法是将../替换成/static/, 如下图所示.
这种hardcoding做法弊端是在当路径变更时, 需要重新设定路径.
第二种方法是使用load staticfiles的方法
c. 修改register.html引用
将index, login, register页面中的"register.html"替换成{% url 'register' %}, 这样, 不管未来register的url怎么变, html中都不需要手动更改.
顺便, 我们将各页面中的"index.html"替换成{% url 'index' %}, 将各页面中的"login.html"替换成{% url 'login' %}
2. 配置view
在users/views中增加以下代码
class RegisterView(View):
def get(self, request):
return render(request, "register.html", {})
from users.views import LoginView, RegisterView # 新import RegisterView
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/$', RegisterView.as_view(), name="register"), # 新增代码
]
成功加载页面
5. 验证码实现
a. 下载验证码开发库
在Github网站搜索django captcha, 点击进mbi/django-simple-captcha
打开该页面后, 滚动到最底部, 点击进document
打开该页面后, 滚动到底部, 点击installation
打开该页面后, 能看到详细install方法
在cmd命令行输入pip install django-simple-captcha==0.4.6
在settings中installed app加入captcha
接着, 在urls中增加captcha
from django.conf.urls import url, include # 新import include
# 中间代码省略
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/$', RegisterView.as_view(), name="register"),
url(r'^captcha/', include('captcha.urls')), # 新增代码
]
接着, 运行Tools下的run manage.py
在manage命令行中输入makemigrations, 然后输入migrate.
在Navicat中查看新生成的表格, 点击设计表, 查看该表的键设计.
b.Register功能实现
在users/form中增加Register form
from captcha.fields import CaptchaField
# LoginForm代码省略
class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField()
from .forms import LoginForm, RegisterForm # 新import RegisterForm
class RegisterView(View):
def get(self, request):
register_form = RegisterForm() # 实例化RegisterForm
return render(request, "register.html", {'register_form': register_form}) # 将register_form传入register.html
在register.html中增加代码
<div class="form-group marb8 captcha1 ">
<label>验 证 码</label>
{{ register_form.captcha }}
在register.html中修改form id
修改前id是"email_register_form"
<div class="tab-form">
<form id="email_register_form" method="post" action="{% url 'register' %}" autocomplete="off">
<div class="tab-form">
<form id="register_form" method="post" action="{% url 'register' %}" autocomplete="off">
刷新register页面, 查看效果
在页面右击菜单中点击查看源代码, 可以找到captcha自动生成的代码.
在Navicat中查看captcha相关的表, 其中找到一段hashkey是跟浏览器中源代码其中一个input中的字符串是一致的. 其实是浏览器与服务器之间会做验证. 当验证码与hashkey都匹配上的时候, 验证码才算通过.
c. debug验证码功能
在注册时故意输错验证码
在views中打断点位置查看register_form中_error, 可以看到验证码invalid的信息, 证明验证码的功能实现了.
但是该错误信息是英文的, 能否自定义为中文呢?
在users/forms中修改代码
class RegisterForm(forms.Form):
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
captcha = CaptchaField(error_messages={"invalid": "验证码错误"}) # 增加error_message中的invalid的中文写法
在注册页面故意输入错误验证码, 在views断点处观察register_form的error信息, 已经能看到"验证码错误"的字眼.
6. 注册流程实现
a. 取出用户名和密码
在views/RegisterView中改写代码
class RegisterView(View):
def get(self, request):
register_form = RegisterForm()
return render(request, "register.html", {'register_form': register_form})
def post(self, request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("username", "") # 取出POST中的username
pass_word = request.POST.get("password", "") # 取出POST中的password
在views/RegisterView中改写代码
from django.contrib.auth.hashers import make_password # import将密码加密的功能
class RegisterView(View):
def get(self, request):
register_form = RegisterForm()
return render(request, "register.html", {'register_form': register_form})
def post(self, request):
register_form = RegisterForm(request.POST)
if register_form.is_valid():
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user_profile = UserProfile() # 实例化UserProfile
user_profile.username = user_name # 将POST中取出的username传给UserProfile实例中的username
user_profile.email = user_name # 将POST中取出的username传给UserProfile实例中的email
user_profile.password = make_password(pass_word) # 将POST中取出的password加密后传给UserProfile实例中的password
user_profile.save() # 保存UserProfile实例
c. 发送验证码邮件功能实现
邮箱验证的方式: 1. 在用户url链接里加入服务器后台生成的随机字符串; 2. 用户点击链接后, 将链接中字符串取出; 3. 将提取的字符串在数据库中查询, 如能查询得到则激活注册账户, 如查询不到则报错.
users/model中的EmailVerifyRecord model定义的code就是上面所述的随机字符串
在apps下新建utils package
在utils下新建email_send.py
在email_send.py中编写生成随机字符串的代码
from random import Random
def generate_random_str(randomlength=8):
random_str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
random = Random()
for i in range(randomlength):
random_str += chars[random.randint(0, length)]
return random_str
接着编写将随机字符串, email, send_type保存至数据库的代码
from users.models import EmailVerifyRecord
def send_register_email(email, send_type="register"):
email_record = EmailVerifyRecord()
code = generate_random_str(16)
email_record.code = code
email_record.email = email
email_record.send_type = send_type
email_record.save()
编写发送email的代码
首先登陆sina邮箱, 查看邮箱的SMTP服务器, 并将服务状态设置为开启. 如果使用公司内部邮箱, 则询问公司邮箱服务器地址.
在settings中最下方增加代码:
EMAIL_HOST = "smtp.sina.com"
EMAIL_PORT = 25
EMAIL_HOST_USER = "*****@sina.com" # 填上个人的邮箱
EMAIL_HOST_PASSWORD = "******" # 填上个人邮箱密码
EMAIL_USE_TLS = False
EMAIL_FROM = "*****@sina.com" # 与个人邮箱一致
from elearn_py3.settings import EMAIL_FROM
def send_register_email(email, send_type="register"):
# 中间代码省略
email_title = ""
email_body = ""
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
在apps/users/views中增加代码:
from utils.email_send import send_register_email # import发邮件函数
class RegisterView(View):
def get(self, request):
register_form = RegisterForm()
return render(request, "register.html", {'register_form': register_form})
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", {'register_form': register_form}) # 如果验证失败, 则返回注册页面, 并返回register_form的错误信息
在新浪邮箱查看, 能看到发送的验证邮件.