# =====> 用户注册与登录|找回密码 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.给验证码设置过期时间;
时间: 2024-10-11 08:18:59