Django学习记录第五天—注册2

之前我们的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,我们大概就需要自己来写这些正则了。
看一下官方文档

Django学习记录第五天—注册2_第1张图片
image.png

不难发现,EmailField本质还是一个CharField,同事设置了一个默认max_length=254。这样我们直接来用就OK了。

好了说了这么多多余了,回归正题,我们来处理一下邮箱注册。那么问题来了,我们怎么用邮箱发送邮件呢。让我们来看一下。

  • 邮箱绑定

这里我用的是163的邮箱。我们来看一下邮箱需要配置那些东西。
进入到我们的邮箱,然后点击设置,里面有一个SMTP的一个选项。
然后我们点开。

Django学习记录第五天—注册2_第2张图片
image.png

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官方文档

Django学习记录第五天—注册2_第3张图片
image.png

也就是说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这个函数。我们来看一下。

Django学习记录第五天—注册2_第4张图片
image.png

前三个都是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了。

Django学习记录第五天—注册2_第5张图片
image.png

运行后看一下我们的邮箱。

Django学习记录第五天—注册2_第6张图片
image.png

成功接收。邮箱验证我们结束了,接下来就是注册了。

  • 注册

说注册之前,我们需要说明两个问题,一个就是这里我们需要用到form提交,也会用到Post请求,另外一个问题,就是会说到上面说到的form。
之前我们有写一个叫做RegisterForm的类。那么这个Django里的Form有什么用呢,一样来文档看一下。

Django学习记录第五天—注册2_第7张图片
image.png

大致意思就是如果你创建网站或者应用除了显示界面不做任何操作,不接受任何的输入信息,那么你就可以不用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值一样。如:

{{ form.captcha }}
{% csrf_token %}

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里面有什么。

Django学习记录第五天—注册2_第8张图片
image.png

可以看到这是一个dict,然后呢,我们输入的email、password、captcha_0 也就是那个验证码的id 与captcha_1 我们输入的验证码都传递了过来,同时我们也可以明白了,captcha通过captcha_0在数据库找到对应的值然后与我们输入的作比较,从而来验证。

这之后我们可以使用form.is_valid()方法来看一下,是否验证成功。如果验证成功,我们在进行保存信息,发送邮件等操作,如果失败我们需要做错误处理。
我们来看一下错误情况,form有什么变化。

Django学习记录第五天—注册2_第9张图片
执行is_valid之前

对比一下之前与之后

Django学习记录第五天—注册2_第10张图片
执行is_valid之后

多了一个cleaned_data 同事errors更新了。cleaned_data中存放的是验证通过的值,而errors中则是错误的值。

然后在看一下都输入正确的情况是什么呢?

Django学习记录第五天—注册2_第11张图片
验证正确的情况

不难发现,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,我们来注册一个账号看一下。运行注册,当然我们跳转界面没有处理,所以注册完成后还是在这个界面,我们看一下数据库有没有改变。

Django学习记录第五天—注册2_第12张图片
EmailValidateModel表

我们可以看到EmailValidateModel表中已经多了一行数据,就是我们刚才放的验证码。

image.png

对比一下邮箱里的信息,没问题。

image.png

我们的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修改一下,大家可能对{{ }} {% %}使用不是很清楚,大家可以看一下文档

然后让我们看一下效果。

Django学习记录第五天—注册2_第13张图片
image.png

没问题,到这里我们的注册基本就完成了,当然,这个实现很粗糙,比如邮箱是否已经注册我们并没有做验证。

带后续,这里貌似用的时间有点长了。

资料下载地址
资料直接下载

坚持三十天,一起加油!

你可能感兴趣的:(Django学习记录第五天—注册2)