之前我们的html跟验证码已经处理完成,接下来我们来解决一下邮箱注册,为什么使用邮箱注册呢,额。。。大概是因为免费,如果是有手机验证码,我们还需要买服务,所以这里我们就使用邮箱来处理。OK,下面我们开始。
- 邮箱注册流程
手机注册流程跟邮箱注册流程很相似,一样的是输入邮箱/手机,获取设置密码,获取验证码,然后校验,成功后就注册成功了。
OK,我们来做一下。
- EmailField
额,说到这里我们修改一个错误。
上一篇我们说的form.py中email我们用的是CharField,我们可以使用Django跟我提供的EmailField,这样可以省略我们很多事情。
我们看一下EmailField里面有什么。
class EmailField(CharField):
widget = EmailInput
default_validators = [validators.validate_email]
def clean(self, value):
value = self.to_python(value).strip()
return super(EmailField, self).clean(value)
有一个validators.validate_emailde我们看啊看这个validate_emailde是什么的存在。
validate_email = EmailValidator()
EmailValidator又是什么呢?看一下~~
class EmailValidator(object):
message = _('Enter a valid email address.')
code = 'invalid'
user_regex = _lazy_re_compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string
re.IGNORECASE)
domain_regex = _lazy_re_compile(
# max length for domain name labels is 63 characters per RFC 1034
r'((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+)(?:[A-Z0-9-]{2,63}(?
比较长,我们就看这一部分,不难看出这里有很多正则表达式,如果我们不适用EmailField,我们大概就需要自己来写这些正则了。
看一下官方文档
不难发现,EmailField本质还是一个CharField,同事设置了一个默认max_length=254。这样我们直接来用就OK了。
好了说了这么多多余了,回归正题,我们来处理一下邮箱注册。那么问题来了,我们怎么用邮箱发送邮件呢。让我们来看一下。
- 邮箱绑定
这里我用的是163的邮箱。我们来看一下邮箱需要配置那些东西。
进入到我们的邮箱,然后点击设置,里面有一个SMTP的一个选项。
然后我们点开。
OK,然后我们需要设置在项目settings中配置一下。
EMAIL_HOST = 'smtp.163.com' #邮件服务器 在邮箱设置内可以找到
EMAIL_PORT = 25 #固定端口
EMAIL_HOST_USER = '[email protected]' #邮箱用户名
EMAIL_HOST_PASSWORD = '' #这个我们看一下官方文档
EMAIL_USE_TLS = False #默认False
EMAIL_FROM = '[email protected]' #与用户名保持一致
关于EMAIL_HOST_PASSWORD官方文档
也就是说EMAIL_HOST_PASSWORD一般是与EMAIL_HOST_USER联合使用,一起认证SMTP服务器,如果为''将不做验证。
之后我们怎么做的,让我们来写一个发送Email的文件。
创建utils文件夹,在里面创建MyEmail.py文件。
然后引入头文件。
from random import Random
from django.core.mail import send_mail
from TestProject.settings import EMAIL_FROM
加入随机生成验证码的函数:
def generate_random_str(random_length=4):
random_str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkIiMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
random = Random()
for i in range(random_length):
random_str += chars[random.randint(0, length)]
return random_str
然后我们来写入发送邮件的函数。注意哦,django的发送邮件的函数是send_mail,我们定义函数的时候不要使用这个函数名哦!
def send_your_email(email):
email_title = '鲸之网在线注册激活链接'
email_body = '请点击下面的连接激活你的账号: http://127.0.0.1:8000/active/{0}'.format(generate_random_str(4))
send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
if send_status:
pass
最主要的就是send_mail这个函数。我们来看一下。
前三个都是string也就是,主题,消息,还有form_email,还有最后要发给那个Email。是不是很简单,其实这些简单都是假象,django帮我们省去了很多步骤,我们现在只是使用。
配置完成我们来验证一下。
在Views.py中加入实验一下,注意这里的代码后期会删掉,只是作为验证,跟新后的RegisterView
from utils.MyEmail import send_your_email
class RegisterView(View):
def get(self, request):
form = RegisterForm()
send_your_email('[email protected]') #这一行后期会删除哦!
return render(request, 'register.html', {
'form': form,
})
运行看一下效果。我们可以在send_your_email中加一个断点看send_status的返回值是什么。
返回的是一个1,也就是发送成功了,不成功就是0了。
运行后看一下我们的邮箱。
成功接收。邮箱验证我们结束了,接下来就是注册了。
- 注册
说注册之前,我们需要说明两个问题,一个就是这里我们需要用到form提交,也会用到Post请求,另外一个问题,就是会说到上面说到的form。
之前我们有写一个叫做RegisterForm的类。那么这个Django里的Form有什么用呢,一样来文档看一下。
大致意思就是如果你创建网站或者应用除了显示界面不做任何操作,不接受任何的输入信息,那么你就可以不用form了,否则就赶紧用起来吧。
Django提供一些工具与文档去帮助你去接受网站请求然后处理与返回他们。
也就是说当我们有输入信息的时候我们就可以使用form来做。很巧的是验证码,邮箱,密码都是输入信息。所以我们可以使用form来做。
首先我们看一下怎么使用,根据文档我们发现,我们需要导入文件
from django import forms
然后来编写我们的From
class RegisterForm(forms.Form):
email = forms.EmailField()
password = forms.CharField(min_length=8) #最少8位
captcha = CaptchaField()
我们在这里需要注意一个地方,email 与 password都不是随意起得,这要需要与html中标签的name值一样。如:
id = 'id_password'的input标签的name为password 所以我们上面的
form才有了password。这里十分重要!!!
同时这里还有一个十分重要的事情,为了防止我们的form被黑客获取,我们需要加一个 {% csrf_token %}这个很关键,很关键!!!
接下来我们怎么用,使用起来很方便。来到view中。先编写我们的post方法。
class RegisterView(View):
def get(self, request):
form = RegisterForm()
return render(request, 'register.html', {
'form': form,
})
#新添加的post方法
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
return render(request, 'register.html', {})
else:
return render(request, 'register.html', {})
注意!!! Form需要一个参数,就是你的request.POST这个参数,我们加断点来看一下这个POST里面有什么。
可以看到这是一个dict,然后呢,我们输入的email、password、captcha_0 也就是那个验证码的id 与captcha_1 我们输入的验证码都传递了过来,同时我们也可以明白了,captcha通过captcha_0在数据库找到对应的值然后与我们输入的作比较,从而来验证。
这之后我们可以使用form.is_valid()方法来看一下,是否验证成功。如果验证成功,我们在进行保存信息,发送邮件等操作,如果失败我们需要做错误处理。
我们来看一下错误情况,form有什么变化。
对比一下之前与之后
多了一个cleaned_data 同事errors更新了。cleaned_data中存放的是验证通过的值,而errors中则是错误的值。
然后在看一下都输入正确的情况是什么呢?
不难发现,errors中变成了空,cleaned_data中是我们验证成功的值。
OK,万事俱备,只剩下处理验证之后的数据了。
- 验证成功,我们要做什么?
当然是保存到数据库喽~ 加密之前我们需要多我们的密码进行加密,总不能明文保存吧,这太暴露了~
from django.contrib.auth.hashers import make_password
#更新后的post
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
#我们刚才说过POST其实是个dict所以可以使用['']来取值,由于已经验证过,我们不需要使用get
password = request.POST['password']
email = request.POST['email']
user = UserProfile()
user.password = make_password(password)
user.email = email
user.save()
send_your_email(email)
return render(request, 'register.html', {
'form': form,
})
else:
return render(request, 'register.html', {
'form': form,
})
在保存账号的同时,我们还需要保存我们发送的验证码。
我们来写一下models.py
class EmailValidateModel(models.Model):
add_time = models.DateField(verbose_name=u'添加时间', default=datetime.now())
email = models.EmailField(verbose_name=u'邮箱')
validate_code = models.CharField(max_length=20, verbose_name=u'验证码')
class Meta:
verbose_name = u'邮箱验证码信息'
verbose_name_plural = verbose_name
def __unicode__(self):
return self.email
makemigrations users
migrate users
更新一下我们的发送邮件函数
def send_your_email(email):
code = generate_random_str(4)
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:
model = EmailValidateModel()
model.email = email
model.validate_code = code
model.save()
OK,我们来注册一个账号看一下。运行注册,当然我们跳转界面没有处理,所以注册完成后还是在这个界面,我们看一下数据库有没有改变。
我们可以看到EmailValidateModel表中已经多了一行数据,就是我们刚才放的验证码。
对比一下邮箱里的信息,没问题。
我们的UserProfile里也有了数据,OK,很完美。
- 验证失败,我们做什么
我们需要显示我们的错误信息。我们知道我们的error都放在了form的errors中,所以我们可以将errors传过去。
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
...
...
...
else:
return render(request, 'register.html', {
'error': form.errors,
'form': form,
})
我们只需要将这个传过去即可。
html中我们怎么修改呢
{{ form.captcha }}
{% for key, value in error.items %}{{ value }}{% endfor %}
这里只需要将我们的error这个div修改一下,大家可能对{{ }} {% %}使用不是很清楚,大家可以看一下文档
然后让我们看一下效果。
没问题,到这里我们的注册基本就完成了,当然,这个实现很粗糙,比如邮箱是否已经注册我们并没有做验证。
带后续,这里貌似用的时间有点长了。
资料下载地址
资料直接下载