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