美文网首页Django-mxonline实战
强力Django第六章9-10邮箱注册验证和激活

强力Django第六章9-10邮箱注册验证和激活

作者: L_luky | 来源:发表于2018-04-28 13:09 被阅读0次

    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>邮&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱</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>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</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>验&nbsp;证&nbsp;码</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,表示已激活状态。

    image.png
    最后我们用邮箱登陆,一切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/随机输入一些字符串

    image.png

    相关文章

      网友评论

        本文标题:强力Django第六章9-10邮箱注册验证和激活

        本文链接:https://www.haomeiwen.com/subject/wfwwlftx.html