00-简单的用户注册|登录|修改密码|邮箱激活 |Django


# =====> 用户注册与登录|找回密码
1.页面没有逻辑操作
    from django.views.generic import TemplateView
    urlpatterns = [
        url(r'^$', TemplateView.as_view(template_name="index.html"))
    ]
# 如果页面有逻辑操作就需要配置视图函数;
    from django.shortcuts import render
    
    def user_login(requet):
        if request.method == "POST":
            user_name = request.POST.get("username", "")
            pass_word = request.POST.get("password", "")
            
            2.authenticate用户认证方法
            from django.contrib.auth import authenticate,login
            # 验证用户名密码是否正确
            user = authenticate(username=user_name, password=pass_word)
            # login()方法
            if user is not None:
                login(request, user)
                return render(request, "index.html", locals())
            else: 
                return render(request, "login.html", locals())
                # ======================================>>index.html
                # ----->>> 在登录成功之后跳转首页
                # 注册与登录的form就变成了登录状态,需要在前端做判断;
                {% if request.user.is_authenticated %}
                    ...
                    {% else %}
                    ...
                {% endif %}
                # ===================================================
        elif request.method == "GET":
            return render(request, "login.html", locals())

3.自定义后台auth认证方法-->>> 通过邮箱或者用户名登录
    # ①在settings.py文件中重载变量
    AUTHENTICATION_BACKENDS = (
        'users.views.CustomBackend',  # 自定义类
    )
    # ②自定义认证方法
    from django.contrib.auth.backends import ModelBakend
    # UserProfile是用户表
    from .models import UserProfile
    
    
    # 将这个类配置到settings.py文件中
    from django.db.models import Q
    class CustomerBackend(ModelBackend):
        # 传入两个关键词参数
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                user = UserProfile.objects.get(Q(username=username)|Q(email=username))
                # 存在数据库的用户名是加密的,所有不能get
                # 通过user中的check_password()方法,检测密码是否正确
                if user.check_password(password):
                    # 用户名密码正确,返回user对象
                    return user
            # 如果get不到数据,或者多个数据,就返回异常
            except Exception as e:
                return None
    
4.基于类的用户登录
    # views.py
    from django.views.generic.base imoprt View
    # View这视图类中,有类似http的get,post等方法
    
    class LoginView(View):
        def get(self, request):
            return render(request, "login.html", locals())
        
        def post(self, request):
            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:
                login(request, user)
                return render(request, "index.html")
            else:  
                return render(request, "login.html", {"msg":"用户名密码错误"})
    # urls.py
    from django.views.generic import TemplateView
    urlpatterns = [
        url(r'login/$', LoginView.as_view(), name="login")
    ]
    
5.form表单验证
    # ①myforms.py
        from django import forms
        
        class LoginForm(forms.Form):
            username = forms.CharField(
                required=True,
            )
            password = forms.CharField(
                required=True,
            )
    # 将验证成功之后的业务逻辑添加到视图中
    # ②views.py
        from django.views.generic.base imoprt View
        # View这视图类中,有类似http的get,post等方法
        
        class LoginView(View):
            def get(self, request):
                return render(request, "login.html", locals())
            
            def post(self, request):
                # 创建表单对象
                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:
                        # 执行登录
                        login(request, user)
                        return render(request, "index.html")
                    else:
                        # 登录不成功
                        return render(request, "login.html", {"msg":"用户名密码错误"})
                else:  
                    # 同时返回表单验证错误信息
                    return render(request, "login.html", {'login_form':login_form})

6.django中login()函数实现的原理
# session&cookie
# 请看相关博客补充

7.注册功能
    # 1.显示注册页面
        # views.py
        from django.views.generic.base import View
        
        class RegisterView(View):
            def get(self, request):
                return render(request, "register.html", locals())

        # urls.py
        from django.views.generic import TemplateView
        
        urlpatterns = [
            url(r'register', RegisterView.as_view(), name="register")
        ]

    # 2.用于生成图片验证码的第三方库django-simple-captcha==0.4.6
            pip install django-simple-captcha==0.4.6
        # 添加到应用配置中
            'captcha'
        # 迁移生成表
        # 配置urlconf
    
    # 3.RegisterForm注册表单验证
        from django import forms
        from captcha.field import CaptchaField
        
        class RegisterForm(forms.Form):
            email = forms.EmailField(
                required=True
            )
            password = forms.CharField(
                required=True
            )
            # 验证码input框
            captcha = CharField(
                error_messages={"invalid":"验证码错误"}
            )
    # 4.在视图中操作表单验证逻辑
        # views.py
        from django.views.generic.base import View
        from .myform import RegisterForm
        
        class RegisterView(View):
            def get(self, request):
                register_form = RegisterForm()
                return render(request, "register.html", locals())
            
            def post(self, request):
                register_form = RegisterForm(request.POST)
                # 如果格式校验成功
                if register_form.is_valid():
                    # 注册流程
                    # 取出表单输入数据
                    user_name = request.POST.get("email", "")
                        # 判断用户名是否存在
                        if UserProfile.objects.filter(email=user_name):
                            return render(request, "register.html", {'register_form':register_form}, {'msg':'用户已经存在'})
                        else:        
                            password = request.POST.get("password", "")
                            # 创建模型类对象,给将数据存入数据库中
                            user_profile = UseProfile()
                            user_profile.username = user_name
                            user_profile.email = user_name
                            # 数据库中is_active字段来表示是否激活的状态
                            user_profile.is_active = False
                            # 密码加密
                            from django.contrib.auth.hashers import make_password
                            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.html
        # 验证码input框
            {{ register_form.captcha }}

    # 5.发送邮箱激活链接
        # 新建utils->email_send.py
        from users.models import EmailVerifyRecord
        
        def send_register_email(email, send_type='register'):
            # 创建验证码对象
            email_record = EmailVerifyRecord()
            # 生成四个随机字符串
            random_str = random_str(16)
            # 将发送邮件的字段数据事先保存到数据库中
            email_record.code = code
            email_recode.email = email
            email_recode.send_type = send_type
            email_recode.save()

            # 定义文件内容
            email_title = ""
            email_body = ""
            
            if send_type == "0":
                email_title = ""
                email_body = "点击下面链接激活账号:http://127.0.0.1:8000/active/{0}.format(code)"
                # 使用django内部函数直接发送邮件
                from django.core.mail import send_mail
                from 项目.settings import EMAIL_FROM
                # 参数:subject, message, from_email, recipient_list...
                send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
                # 如果发送成功
                if send_status:
                    pass
                
                # 06-10 视频=======-=-=-=-=-=-=||||||||||||||||||||||||||||||~~~~~~~
                
                
                # ===========================>>> 在settings.py文件中写入发送配置
                EMAIL_HOST = "smtp.sina.com"  # 复制相关邮箱客户端SMTP服务器的地址
                EMAIL_PORT = 25
                EMAIL_HOST_USER = "公司邮箱@sina.com"
                EMAIL_HOST_PASSWORD = "*****密码"
                EMAIL_USE_TLS = False
                EMAIL_FROM = "公司邮箱@sina.com"
                # ==============================================================
            
            
        # 生成随机字符串的函数
        import random
        def random_str(num)
            code = ''
            for i in range(num):
                add = random.choice([random.randrange(10), chr(random.randrange(65,91))])
                code+=str(add)
            return code    
                    
        # EmailVerifyRecord表结构
        # models.py
        class EmailVerifyRecord(models.Model):
            code = models.CharField(max_length=20, verbose_name="验证码")
            email = models.EmailField(max_length=50, verbose_name="邮箱")
            send_type = models.CharField(
                verbose_name="验证码类型",
                choices=(
                    ('register', "注册"),
                    ('find', "找回密码")
                )
            )
            send_time = models.DateTimeField(verbose_name="发送时间", default=datetime.time())
    
    # 6.激活邮箱
        # urls.py
        url(r'^active/(?P<active_code>.*)/$', ActiveUserView.as_view(), name='user_active')
        
        # views.py
        class ActiveUserView(View):
            def get(self, request, active_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:
                    # 如果数据库中没有获取到active_code
                    return render(request , 'register_fail.html')
                return render(request, "login.html")
    
        # 再到登录login视图中,添加是否激活is_active的条件
            from django.views.generic.base imoprt View
            # View这视图类中,有类似http的get,post等方法
            
            class LoginView(View):
                def get(self, request):
                    return render(request, "login.html", locals())
                
                def post(self, request):
                    # 创建表单对象
                    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:
                            # 登录不成功
                            return render(request, "login.html", {"msg":"用户名密码错误"})
                    else:  
                        # 同时返回表单验证错误信息
                        return render(request, "login.html", {'login_form':login_form})
    
8.找回用户密码
    # 1.点击找回密码,页面提示输入用户名密码;
    # 2.提交之后后台发送重置密码的链接;
    # 3.重置密码之后跳转登录页面;
    # ----------->> 1.发送重置密码链接
    # views.py
        class ForgetPwdView(View):
            def get(self, request):
                # 实例化form表单对象
                forget_form = ForgetForm()
                
                return render(request, "forgetpwd.html", {'forget_form':forget_form})
            
            def post(self, request):
                # 实例化form表单对象
                forget_form = ForgetForm(request.POST)    
                if forget_form.is_valid():
                    email = request.POST.get()
                    send_register_email(email, 'find')
                    return render(request, "send_success.html")
                else: 
                    # 如果表单验证失败
                    return render(request, "forgetpwd.html", {'forget_form':forget_form})

                    # ------>>> email_send.py
                    # ====================================
                    elif send_type == "find":
                        email_title = "在线注册密码重置链接"
                        email_body = "请点击下面的链接重置密码:http://127.0.0.1:8000/reset/{0}.format(code)"
                        
                        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
                        if send_status:
                            pass
                    # ====================================
    # urls.py
        url(r'^forget/$', ForgetPwdView.as_view(), name="forget_pwd")
                
    # myform.py
        class ForgetForm(forms.Form):
            email = forms.EmailField(required=True)
            captcha = CaptchaField(error_messages={"invalid":"验证码错误"})
                
    # forgetpwd.html
        {{ forget_form.captcha}}
            
    # send_success.html
        <p>邮件发送成功!</p>
                
    # ----------->> 2.重置密码
    # urls.py 
        url(r'^reset/(?P<active_code>.*)/$', ResetView.as_view, name='reset_pwd')        
    # views.py    
        class ResetView(View):
            def get(self, request, active_code):
                all_records = EmailVerifyRecord.objects.filter(code=active_code)
                if all_records:
                    for record in all_records:
                        email = record.email
                        return render(request , 'password_reset.html', {'email':email})
                else:
                    # 如果数据库中没有获取到active_code
                    return render(request , 'register_fail.html')
                return render(request, "login.html")        
    # reset.html
        # 添加一个隐藏的输入框,给后台传递邮箱地址
        <input type="hidden" value="{{email}}">
    # myform.py
        class ModifyPwdForm(forms.Form):
            password1 = forms.CharField(required=True, min_length=5)
            password2 = forms.CharField(required=True, min_length=5)
    # post请求处理修改验证码的逻辑
        from .myforms import ModifyPwdForm
        class ModifyPwdView(View):
            # 重新定义一个form表单类,而不是在ResetView中继续操作;
            # 因为RestView需要传入一个active_code参数;
            def post(self, request):
                modify_forms = ModifyPwdForm(request.POST)
                if modify_form.is_valid():
                    pwd1 = request.POST.get("password1", "")
                    pwd2 = request.POST.get("password2", "")
                    email = request.POST.get("email", "")
                    if pwd1 != pwd2:
                        return render(request, "password_reset.html", {"email":email})
                    user = UserProfile.objects.get(email=email)
                    user.password = make_password(pwd2)
                    user.save()
                    return render(request, "login.html")
                else:
                    email = request.POST.get("email", "")
                    return render(request, "password_reset.html", {"email":emial, "modify_form":modify_form})
                    
    # urls.py
        url(r'^modify_pwd', ModifyPwdView.as_view(), name="modify_pwd")
    # password_reset.htl
        ...action="{% url 'modift_pwd' %}"
    
    # 遗留问题:1.添加一个email_verify字段,表示这个链接是否用过,
    #               在user.save()之后,设置email_verify=True;
    #              再次点击就告诉用户,密码已经修改过了或者失效;
    #            2.给验证码设置过期时间;
    
        
            

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM