1、使用django自带功能实现登录/退出登录

 使用django自带登录功能,前提生成用户(用户注册)使用的是django自带的user,或称models中用户表继承于django自带的user

1.1、登录

 views.py:

from django.contrib.auth import authenticate,login,logoutdef acc_login(request):"""登录页面"""error_msg = ''if request.method == "POST":username = request.POST.get('username')password = request.POST.get('password')user = authenticate(username = username, password = password)if user:login(request,user)return redirect(request.GET.get('next','/index/')) # 如果有next则跳转到next指定的页面,如果没有则跳转到index页面else:error_msg = "Wrong username or password!"return render(request,"login.html",{'error_msg':error_msg})

1.2、退出登录

 views.py:

def acc_logout(request):logout(request)return redirect("/login/")

 urls.py:

from django.urls import path
from NBCRM import viewsurlpatterns = [path('login/',views.acc_login),path('logout/',views.acc_logout,name="logout"),]

 settings.py:

  当某些页面设置了登录才能访问时,用户访问该页面会失败,此时可以在settings中进行下面的设置,指定用户在未登录前访问需登录才能访问的页面时,跳转到指定(登录)页面,执行某些操作,成功后才能访问目标页面。

LOGIN_URL = '/login/'

 登录界面:

 


2.自定义登录方式

1)login相关代码:

def login(request):if request.method == "POST":username = request.POST.get("username")password = request.POST.get("password")user = models.User.objects.filter(username=username, password=password)  # [User Obj, ]if user:# 登陆成功request.session["is_login"] = "1"# request.session["username"] = usernamerequest.session["user_id"] = user[0].id# 1. 生成特殊的字符串# 2. 特殊字符串当成key,在数据库的session表中对应一个session value# 3. 在响应中向浏览器写了一个Cookie Cookie的值就是 特殊的字符串return redirect("/index/")return render(request, "login.html")

2)check_login:

 装饰器,用于检查用户是否登录

from functools import wraps
def check_login(f):@wraps(f)def inner(request, *args, **kwargs):if request.session.get("is_login") == "1":return f(request, *args, **kwargs)else:return redirect("/login/")return inner

3)index:

 首页,访问前判断用户是否已登录,登录则成功访问,未登录则跳转登录页面

@check_login
def index(request):user_id = request.session.get("user_id")# 根据id去数据库中查找用户user_obj = models.User.objects.filter(id=user_id)if user_obj:return render(request, "index.html", {"user": user_obj[0]})else:return render(request, "index.html", {"user": "匿名用户"})


2.1、session简单介绍

1)session作用

  1. 生成随机字符串
  2. 写到用户浏览器的cookie中
  3. 保存到session中
  4. 在随机字符串对应的字典中设置相关内容

2)session默认过期时间为2周,如果自己设置过期时间,自定义设置过期时间优先级高于默认时间

request.session.set_expiry(value)  # 设置session过期时间

 默认的过期时间是两周,如果自己设置了过期时间,这样自己设定的优先级就会高于默认的

 如果value是个整数,session会在些秒数后失效。

 如果value是个datatime或timedelta,session就会在这个时间后失效。

 如果value是0,用户关闭浏览器session就会失效。

 如果value是None,session会依赖全局session失效策略。

3)session的相关配置

# settings.py
SESSION_COOKIE_NAME = "sessionid"      # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)

SESSION_COOKIE_PATH = "/"              # Session的cookie保存的路径(默认)

SESSION_COOKIE_DOMAIN = None             # Session的cookie保存的域名(默认)

SESSION_COOKIE_SECURE = False          # 是否Https传输cookie(默认)

SESSION_COOKIE_HTTPONLY = True         # 是否Session的cookie只支持http传输(默认)

SESSION_COOKIE_AGE = 1209600             # Session的cookie失效日期(2周)(默认)

SESSION_EXPIRE_AT_BROWSER_CLOSE = False    # 是否关闭浏览器使得Session过期(默认)

SESSION_SAVE_EVERY_REQUEST = False        # 是否每次请求都保存Session,默认修改之后才保存(默认)

4)Django中对应session的存储方式

Django中支持session,其中内部提供了5种类型的session供开发者使用:

  • 数据库(默认)
  • 缓存
  • 文件
  • 缓存+数据库
  • 加密cookie
1、如果是数据库,需要在settings.py中配置如下:SESSION_ENGINE = 'django.contrib.sessions.backends.db' (引擎(默认))2、如果是缓存session,需要在settings.py中配置如下:SESSION_ENGINE = 'django.contrib.sessions.backends.cache'(引擎)SESSION_CACHE_ALIAS= 'default'  使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置3、 如果是文件session, 需要在settings.py中配置如下:SESSION_ENGINE = 'django.contrib.sessions.backends.file' (引擎)SESSION_FILE_PATH=None  缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()   4、如果是缓存+数据库session,需要在settings.py中配置如下:SESSION_ENGINE='django.contrib.sessions.backends.cached_db'       (引擎)


3、利用django自带登录功能,实现自定义用户名或邮箱登录,及用户注册(邮箱激活)、忘记密码等功能

3.1 实现用户注册功能 

 

 3.1.1 验证码实现 --第三方库:Captcha

  1)安装captcha

pip install  django-simple-captcha

  2)在我们项目的setting.py中的INSTALLED_APPS注册captcha。需要注意的是,在INSTALLED_APPS中注册的,都需要经过makemigrations、migrate生成对应的表数据

INSTALLED_APPS = [……'captcha',……
]

  3)配置urls.py

from django.urls import path,include,re_pathurlpatterns = [# 验证码re_path(r'^captcha', include('captcha.urls')),
]

通过上述几步,我们就能在项目中正常使用captcha了。用法很简单:

  1)后台用到验证码的地方:

from captcha.fields import CaptchaFieldclass RegisterForm(forms.Form):"""注册表单验证"""captcha = CaptchaField(error_messages={'invalid':'验证码错误'})

  2)前端页面展示 --关于验证码:

<label>验&nbsp;证&nbsp;码</label>
{{ register_form.captcha }}

使用captcha实现验证码的好处:不需要我们判断前端验证码输入与原验证码是否一致(内部已实现了判断),只需要按上述几个步骤操作,即可实现注册/登录页面的验证码验证功能

 3.1.2 实现注册功能

  结合第三方库captcha,实现附有验证码的注册功能

  1)注册功能 --form表单验证

from django import forms
from django.core.exceptions import ValidationErrorfrom captcha.fields import CaptchaFieldclass RegisterForm(forms.Form):"""注册表单验证"""email = forms.EmailField(required=True)password = forms.CharField(required=True,min_length=6)# 验证码 内部已经包含判断验证码是否正确,不需要进行下述的验证码验证代码编写captcha = CaptchaField(error_messages={'invalid':'验证码错误'})# 验证码验证,使用第三方库captcha时不需要再判断,属于画蛇添足# def clean_captcha(self):#     print("captcha:",self.request.session.get('code'))#     print("valid_code:",self.cleaned_data.get('code'))#     if self.request.session.get('code').upper() == self.cleaned_data.get('code').upper():#         return self.cleaned_data['code']#     else:#         raise ValidationError('验证码不正确')# 自定义方法(局部钩子),密码必须包含字母和数字def clean_password(self):if self.cleaned_data.get('password').isdigit() or self.cleaned_data.get('password').isalpha():raise ValidationError('密码必须包含数字和字母')else:return self.cleaned_data['password']# 自定义方法(全局钩子, 检验两个字段),可用于检验两次密码是否一致;# def clean(self):#     if self.cleaned_data.get('password') != self.cleaned_data.get('password2'):#         raise ValidationError('密码不一致')#     else:#         return self.cleaned_data

forms.py

  2)views.py:

def register(request):"""用户注册 """if request.method == "POST":register_form = forms.RegisterForm(request.POST)if register_form.is_valid():user_name = request.POST.get('email',None)if UserProfile.objects.filter(email=user_name):# 用户已经存在,不需要再注册return render(request,'register.html',{'msg':'用户已经存在','register_form':register_form})pass_word = request.POST.get('password', None)# 将密码加密后再保存pass_word = make_password(pass_word)UserProfile.objects.create(username=user_name,email=user_name,is_active=False,password=pass_word)email_send_status = email_send.send_register_email(user_name, 'register')  # 发送邮件,用于用户激活账号if email_send_status: # 状态为1,表示邮件发送成功email_send_success = True  # 用于前端判断发送邮件的类型return render(request,'send_email_success.html',locals())else:# status_form = True #用于前端注册时判断是否填充客户输入原数据return render(request, 'register.html', {'msg':'用户名或密码格式错误','register_form':register_form})else:register_form = forms.RegisterForm()return render(request,'register.html',locals())

  3)urls.py配置:

from django.urls import path
from web_online import viewsurlpatterns = [path('register/',views.register, name='register'),# 验证码urlre_path(r'^captcha',include('captcha.urls')),]

  4)HTML前端代码(仅供参考):

<!DOCTYPE html>
{% load staticfiles %}
<html><head><meta charset="UTF-8"><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" ><title>慕学在线注册</title><link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}"><link rel="stylesheet" type="text/css" href="{% static 'css/login.css' %}"></head>
<body>
<div class="loginbox dialogbox"><h1>账号登录</h1><div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div><div class="cont"><form id="jsLoginForm" autocomplete="off"><div class="box"><span class="word3">用户名</span><input type="text" name="account_l" id="account_l" placeholder="手机号/邮箱" /></div><div class="box"><span class="word2">密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</span><input type="password" name="password_l" id="password_l" placeholder="请输入您的密码"/></div><div class="error btns login-form-tips" id="jsLoginTips"></div> <!--登录错误提示--><div class="btns"><span><input type="checkbox" id="jsAutoLogin" />&nbsp;自动登录</span><span class="forget btn fr">忘记密码</span></div><div class="button"><input type="button" value="登录" id="jsLoginBtn" /></div><div class="btns"><span class="fr">没有账号?<span class="regist btn">立即注册</span></span></div></form></div>
</div>
<div class="dialog" id="jsDialog"><!--提示弹出框--><div class="successbox dialogbox" id="jsSuccessTips"><h1>成功提交</h1><div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div><div class="cont"><h2>您的需求提交成功!</h2><p></p></div></div><div  class="noactivebox dialogbox" id="jsUnactiveForm" ><h1>邮件验证提示</h1><div class="close jsCloseDialog"><img src="{% static 'images/dig_close.png' %}"/></div><div class="center"><img src="{% static 'images/send.png' %}"/><p>我们已经向您的邮箱<span class="green" id="jsEmailToActive">12@13.com</span>发送了邮件,<br/>为保证您的账号安全,请及时验证邮箱</p><p class="a"><a class="btn" id="jsGoToEmail" target="_blank" href="http://mail.qq.com">去邮箱验证</a></p><p class="zy_success upmove"></p><p style="display: none;" class="sendE2">没收到,您可以查看您的垃圾邮件和被过滤邮件,也可以再次发送验证邮件(<span class="c5c">60s</span>)</p><p class="sendE">没收到,您可以查看您的垃圾邮件和被过滤邮件,<br/>也可以<span class="c5c green" id="jsSenEmailAgin" style="cursor: pointer;">再次发送验证邮件</span></p></div></div>
</div><div class="bg" id="dialogBg"></div>
<header><div class="c-box fff-box"><div class="wp header-box"><p class="fl hd-tips">慕学在线,在线学习平台!</p><ul class="fr hd-bar"><li>服务电话:<span>4001008031</span></li><li><a href="{% url 'login' %}">[登录]</a></li><li class="active"><a href="{% url 'register' %}">[注册]</a></li></ul></div></div>
</header>
<section><div class="c-box bg-box"><div class="login-box clearfix"><div class="hd-login clearfix"><a class="index-logo" href="/index/"></a><h1>用户注册</h1><a class="index-font" href="/index/">回到首页</a></div><div class="fl slide"><div class="imgslide"><ul class="imgs"><li><a href=""><img width="483" height="472" src="{% static 'images/57a801860001c34b12000460.jpg' %}" /></a></li><li><a href=""><img width="483" height="472" src="{% static 'images/57a801860001c34b12000460.jpg' %}" /></a></li><li><a href=""><img width="483" height="472" src="{% static 'images/57a801860001c34b12000460.jpg' %}" /></a></li></ul></div><div class="unslider-arrow prev"></div><div class="unslider-arrow next"></div></div><div class="fl form-box"><div class="tab"><!--<h2 class="active">手机注册</h2>--><h2>邮箱注册</h2></div><div class="tab-form"><form id="email_register_form" method="post" action="{% url 'register' %}" autocomplete="off">{% csrf_token %}<div class="form-group marb20 {% if register_form.errors.email.0 %} errorput {% endif %}"><label>邮&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;箱</label><input  type="text" id="id_email" name="email" {% if register_form.email.value %} value="{{ register_form.email.value }}" {% endif %} placeholder="请输入您的邮箱地址" /></div><div class="error btns" id="jsEmailTips">{{ register_form.errors.email.0 }}</div><div class="form-group marb8 {% if register_form.errors.password.0 %} errorput {% endif %}"><label>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</label><input type="password" id="id_password" name="password"  {% if register_form.password.value %} value="{{ register_form.password.value }}" {% endif %} placeholder="请输入6-20位非中文字符密码" /></div><div class="error btns" id="jsEmailTips">{{ register_form.errors.password.0 }}</div><div class="form-group marb8 captcha1 {% if register_form.errors.captchal.0 %} errorput {% endif %}">
{#                            <label>验&nbsp;证&nbsp;码</label>#}
{#                            {{ register_form.captcha }}#}<input name='code' type="text" placeholder="验证码" />{{ register_form.captcha }}</div><div class="error btns" id="jsEmailTips">{{ register_form.errors.captcha.0 }}</div><div class="error btns" id="jsEmailTips">{{ msg }}</div><div class="auto-box marb8"></div><input class="btn btn-green" id="jsEmailRegBtn" type="submit" value="注册" /></form></div><p class="form-p">已有账号?<a href="{% url 'login' %}">[立即登录]</a></p></div></div></div>
</section><input id="isLogin" type="hidden" value="False"/>
<script src="{% static 'js/jquery.min.js' %}" type="text/javascript"></script>
<script src="{% static 'js/unslider.js' %}" type="text/javascript"></script>
<script src="{% static 'js/validateDialog.js' %}"  type="text/javascript"></script>
<script src="{% static 'js/login.js' %}"  type="text/javascript"></script>
</body>
</html>

register.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>{% if email_send_success %}<p>【注册账号激活】邮件已发送,请移步邮箱中查收!</p>{% else %}<p>【密码重置】邮件已发送,请移步邮箱中查收!</p>{% endif %}</body>
</html>

send_email_success.html

 3.1.3  注册账号激活 

  在上述注册功能实现过程中涉及到邮件激活账号:email_send.send_register_email(user_name,'register') , 下面实现注册账号激活功能

   注意:用户账号激活时,本质是通过is_active=True来实现的,如果将is_staff也设置为True,则表示该用户可以登录我们项目的django后台。切记,只有is_active、is_staff同时为True,才能登录django后台。

  1)email_send.py:用于给用户发送邮件,实现下述功能

  • 账号激活
  • 忘记密码,重置密码
  • 修改密码

import random
from users.models import EmailVerifyRecord
from django.core.mail import send_mail
from web_online import settingsdef random_str(random_length=16):"""默认生成16位随机字符串"""str = ''# 生成字符串的可选字符串chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'length = len(chars) - 1# ran_dom = random.Random()for i in range(random_length):str += chars[random.randint(0, length)]return str# 发送邮件
def send_register_email(email, send_type="register"):"""发送邮件发送前将当前注册用户保存到数据库,方便后台激活账号时能在数据库中找到对应的注册用户"""if send_type == 'update_email': # 修改密码操作code = random_str(4)else:code = random_str(16)# 保存到数据库
    EmailVerifyRecord.objects.create(code=code,email=email,send_type=send_type)# 定义邮箱内容:if send_type == "register":  # 注册激活账号subject = "Mx在线教育注册激活链接"  # 标题email_body = "请复制打开下面的链接激活你的账号:http://127.0.0.1:8000/active/{0}".format(code)  # 文本邮件体sender = settings.DEFAULT_FROM_EMAIL  # 发件人receiver = [email]  # 接收人email_send_status = send_mail(subject, email_body, sender, receiver)return email_send_status# if email_send_status:#     passelif send_type == 'forget':  # 忘记密码 重置密码subject = "Mx在线教育重置密码链接"  # 标题email_body = "请复制打开下面的链接重置密码:http://127.0.0.1:8000/reset/{0}".format(code)  # 文本邮件体sender = settings.DEFAULT_FROM_EMAIL  # 发件人receiver = [email]  # 接收人email_send_status = send_mail(subject, email_body, sender, receiver)return email_send_statuselif send_type == "update_email":  # 修改密码验证码subject = "Mx在线教育邮箱修改验证码"email_body = "你的邮箱验证码为{0}".format(code)sender = settings.DEFAULT_FROM_EMAILreceiver = [email]# 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者listsend_status = send_mail(subject, email_body, sender, receiver)# 如果发送成功if send_status:pass

email_send.py

  2)使用django自带的邮件发送功能,需要在settings.py中配置发送邮件的基本数据:

# 邮箱配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = "smtp.163.com"   #以163邮箱为例,SMTP服务器(邮箱需要开通SMTP服务)
EMAIL_HOST_PASSWORD = '******'     #SMTP服务授权码
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER = "13*******@163.com"    #我的163邮箱帐号
EMAIL_PORT = 25     #163邮箱SMTP服务端口
EMAIL_USE_TLS = True     # 163、qq邮箱此值为True,aliyun此值为False,163可以忽略此值
# EMAIL_SUBJECT_PREFIX = '[yshblog.com]'     #邮件标题前缀,默认是'[django]'

  3)views.py:

   注册账号激活功能

def user_active(request, accode):"""注册用户账号激活"""if request.method == "GET":ac_records = EmailVerifyRecord.objects.filter(code=accode)if ac_records: # 有当前注册用户five_mintes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)ac_record = ac_records[0]# print("five_mintes_ago:",five_mintes_ago)# print("send_time:",ac_record.send_time)if five_mintes_ago > ac_record.send_time: # 发送时间超过5分钟,返回链接失效页面return render(request, 'active_fail.html')ac_email = ac_record.emailac_user = UserProfile.objects.get(email=ac_email) # 当前注册用户ac_user.is_active = Trueac_user.save()return render(request,'active_success.html',locals())else:return render(request,'active_fail.html')

  4)urls.py配置:

from django.urls import path
from web_online import viewsurlpatterns = [re_path(r'^active/(\w+)/', views.user_active, name='user_active'),  # 邮箱激活账号

]

  5)注册成功返回页面、注册用户失败或链接失效返回页面:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>mx教育邮箱注册成功</title>
</head>
<body>
<h3>恭喜!您已成功激活账号:{{ ac_email }}</h3>
<p style="color: red">点击跳转:<a href="/login/">登录</a></p>
</body>
</html>

active_success.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p style="color: red;">链接已经失效</p>
</body>
</html>

active_fail.html

至此,用户注册及激活功能即完成。



3.2 实现自定义用户名或邮箱登录功能

  3.2.1 userProfile继承于 AbstractUser

    需要注意的是:AbstractUser中定义的email字段不具有唯一性,容易造成多个用户使用同一邮箱,当使用邮箱登录时会造成冲突。因此,需要重写email字段,使其与username字段一样,具备 '唯一'性

from django.db import models
from django.contrib.auth.models import AbstractUserclass UserProfile(AbstractUser):"""用户"""gender_choices = (('male','男'),('female','女'))nick_name = models.CharField('昵称',max_length=32 ,default='')birthday = models.DateField('生日',null=True,blank=True)gender = models.CharField('性别',max_length=8,choices=gender_choices,default='female')adress = models.CharField('地址',max_length=100,default='')mobile = models.CharField('手机号',max_length=11,null=True,blank=True)image = models.ImageField(upload_to='image/%Y/%m',default='image/default.png',max_length=100)email = models.EmailField('邮箱', blank=True,unique=True)  # 重写email字段,加上'唯一'标识class Meta:verbose_name = '用户信息'verbose_name_plural = verbose_namedef __str__(self):return self.username

此时 userProfile表所存字段:

 

 3.2.2 在views中编写登录功能之前,我们需要先写一个form表单,用于用户登录时,对用户名及密码格式进行验证:

     forms.py/LoginForm

from django import formsclass LoginForm(forms.Form):"""登录表单验证"""username = forms.CharField(required=True)password = forms.CharField(required=True, min_length=6)

 3.2.3 接着在views界面中编写我们的登录代码:

from django.shortcuts import render,redirect
from django.contrib.auth import authenticate ,login ,logout
from users.models import UserProfile
from web_online import formsdef mx_login(request):"""登录"""login_form = forms.LoginForm()if request.method == "POST":login_form = forms.LoginForm(request.POST)if login_form.is_valid():user_name = request.POST.get('username',None)pass_word = request.POST.get('password',None)user = authenticate(username=user_name, password=pass_word)if user:if user.is_active:# 只有注册激活才能登陆
                    login(request,user)return redirect('/index/')else:return render(request,'login.html',{'msg': '用户未激活', 'login_form': login_form})else:return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})else:return render(request, 'login.html', {'msg': '用户名或密码格式错误,请重新输入!', 'login_form': login_form})return render(request,"login.html")

简单解析:

 1. is_active:在注册中,我们对成功激活账号的用户设置is_active为True,在登录操作中就可以通过is_active的状态来判断用户是否是注册成功的用户,来决定是否给用户登录权限

 2. authenticate()方法的验证:我们使用的是django自带的authenticate验证, 默认只对用户名、密码进行验证,我们要使用用户名或邮箱进行验证,需要自定义authenticate方法,实现代码如下:

class CustomBackend(ModelBackend):"""用于mx_login用户登录验证需在settings中配置好authenticate验证方式(即在此进行authenticate的相关验证)"""def authenticate(self, request, username=None, password=None, **kwargs):# 重写authenticate方法try:user = UserProfile.objects.get(Q(username=username)|Q(email=username))if user.check_password(password):"""1.在注册时,我们对密码使用了加密处理(django下的make_password),因此在登录验证密码时需要先将明文密码加密后才能跟数据库中已加密后的密码进行比较2.check_password()是AbstractUser类中的方法,UserProfile继承于AbstractUser,check_password会加密明文密码后,与数据库密码做对比,再进行判断两密码是否一致3.验证如果为True,表示密码一致;为False,表示密码不一致"""return userelse:return Noneexcept Exception as e:return None

 以上基本实现了自定义登录功能验证,但要验证流程中的authenticate验证走我们自定义的authenticate验证,需要在settings.py中配置AUTHENTICATION_BACKENDS ,如不配置,默认会走django自带的authenticate验证:

AUTHENTICATION_BACKENDS = ( # 登录认证设置'web_online.views.CustomBackend', #CustomBackend所在路径
)

 3.2.4 url配置:

from django.urls import path
from web_online import viewsurlpatterns = [path('login/',views.mx_login, name='login'),]

 3.2.5 html配置:

   注意:HTML前端代码未附带css、js代码,仅供参考

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" ><title>慕学在线网登录</title><link rel="stylesheet" type="text/css" href="/static/css/reset.css"><link rel="stylesheet" type="text/css" href="/static/css/login.css">
</head>
<body>
<div class="dialog" id="jsDialog">
<!--提示弹出框,用于找回密码操作时的提示-->
<div class="successbox dialogbox" id="jsSuccessTips"><h1>成功提交</h1><div class="close jsCloseDialog"><img src="/static/images/dig_close.png"/></div><div class="cont"><h2>您的需求提交成功!</h2><p></p></div>
</div>
<div  class="noactivebox dialogbox" id="jsUnactiveForm" ><h1>邮件验证提示</h1><div class="close jsCloseDialog"><img src="/static/images/dig_close.png"/></div><div class="center"><img src="/static/images/send.png"/><p>我们已经向您的邮箱<span class="green" id="jsEmailToActive">12@13.com</span>发送了邮件,<br/>为保证您的账号安全,请及时验证邮箱</p><p class="a"><a class="btn" id="jsGoToEmail" target="_blank" href="http://mail.qq.com">去邮箱验证</a></p><p class="zy_success upmove"></p><p style="display: none;" class="sendE2">没收到,您可以查看您的垃圾邮件和被过滤邮件,也可以再次发送验证邮件(<span class="c5c">60s</span>)</p><p class="sendE">没收到,您可以查看您的垃圾邮件和被过滤邮件,<br/>也可以<span class="c5c green" id="jsSenEmailAgin" style="cursor: pointer;">再次发送验证邮件</span></p></div>
</div>
</div>
<div class="bg" id="dialogBg"></div>
<header><div class="c-box fff-box"><div class="wp header-box"><p class="fl hd-tips">慕学在线网,在线学习平台!</p><ul class="fr hd-bar"><li>服务电话:<span>33333333</span></li><li class="active"><a href="{% url 'login' %}">[登录]</a></li><li><a href="{% url 'register' %}">[注册]</a></li></ul></div></div>
</header>
<section><div class="c-box bg-box"><div class="login-box clearfix"><div class="hd-login clearfix"><a class="index-logo" href="/index/"></a><h1>用户登录</h1><a class="index-font" href="/index/">回到首页</a></div><div class="fl slide"><div class="imgslide"><ul class="imgs"><li><a href=""><img width="483" height="472" src="/static/images/mysql.jpg"/></a></li><li><a href=""><img width="483" height="472" src="/static/images/mysql.jpg"/></a></li><li><a href=""><img width="483" height="472" src="/static/images/mysql.jpg"/></a></li></ul></div><div class="unslider-arrow prev"></div><div class="unslider-arrow next"></div></div><div class="fl form-box"><h2>帐号登录</h2><form action="/login/" method="post" autocomplete="off">{% csrf_token %}<div class="form-group marb20 {% if login_form.errors.username.0 %} errorput {% endif %}"><label>用&nbsp;户&nbsp;名</label><input name="username" id="account_l" type="text" placeholder="手机号/邮箱" {% if login_form.username.value %}value="{{ login_form.username.value }}"{% endif %}/></div><div class="error btns login-form-tips" id="jsLoginTips">{{ login_form.errors.username.0 }}</div><div class="form-group marb8 {% if login_form.errors.password.0 %} errorput {% endif %}"><label>密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</label><input name="password" id="password_l" type="password" {% if login_form.password.value %}value="{{ login_form.password.value }}"{% endif %} placeholder="请输入您的密码"/></div><div class="error btns login-form-tips" id="jsLoginTips">{{ login_form.errors.password.0 }}</div><div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div><div class="auto-box marb38"><a class="fr" href="#">忘记密码?</a>
{#                        <a class="fr" href="{% url 'forgetpwd' %}">忘记密码?</a>#}</div><input class="btn btn-green" id="jsLoginBtn" type="submit" value="立即登录 > "/><input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy'/>{% csrf_token %}</form><p class="form-p">没有慕学在线网帐号?<a href="{% url 'register' %}">[立即注册]</a></p></div></div></div>
</section>
<script src="/static/js/jquery.min.js" type="text/javascript"></script>
<script src="/static/js/unslider.js" type="text/javascript"></script>
<script src="/static/js/login.js"  type="text/javascript"></script>
</body>
</html>

login.html



 3.3 退出登录功能

   3.3.1 退出登录

     实现退出登录功能很简单,在views.py中编写退出登录代码:

from django.contrib.auth import logoutdef mx_logout(request):"""退出登录"""logout(request)return redirect('/login/')  # 返回登录页面

    3.3.2 url配置:

from django.urls import path
from web_online import viewsurlpatterns = [path('logout/',views.mx_logout, name='logout'),]

注:退出登录功能,没有HTML前端代码



3.4 实现忘记密码、找回密码功能

 点击 [忘记密码],进入找回密码,根据注册邮箱,找回密码

      

 3.4.1 根据注册用户邮箱,发送验证邮件

  1)views.py:

def forget_pwd(request):"""忘记密码,通过邮箱找回密码"""message = {}if request.method == "POST":forget_pwd_form = forms.ForgetPwdForm(request.POST)if forget_pwd_form.is_valid():email = request.POST.get('email',None)user_objs = UserProfile.objects.filter(email=email)if user_objs:  # 判断邮箱是否存在send_status = email_send.send_register_email(email,'forget')if send_status:  # 邮件发送成功email_send_success = False  # 用于前端判断发送邮件的类型return render(request,'send_email_success.html',locals())else:message['msg'] = '该邮箱不存在'message['status'] = Truereturn render(request, 'forgetpwd.html', {'message': message, 'forget_pwd_form': forget_pwd_form})else:  # form表单验证不通过message['msg'] = '邮箱或验证码错误'message['status'] = Truereturn render(request,'forgetpwd.html',{'message':message,'forget_pwd_form' : forget_pwd_form})else:forget_pwd_form = forms.ForgetPwdForm()return render(request,'forgetpwd.html',{'forget_pwd_form' : forget_pwd_form})

  2)forms.py 表单验证:

class ForgetPwdForm(forms.Form):"""忘记密码"""email = forms.EmailField(required=True)captcha = CaptchaField(error_messages={'invalid': '验证码错误'})

  3)urls.py:

from django.urls import path
from web_online import viewsurlpatterns = [path('forgetpwd/', views.forget_pwd, name='forgetpwd'),  # 忘记密码

]

  4)HTML前端代码:

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"><title>慕学网首页</title><link rel="stylesheet" type="text/css" href="/static/css/reset.css"><link rel="stylesheet" type="text/css" href="/static/css/login.css">
</head>
<body>
<!--提示弹出框-->
<div class="successbox dialogbox" id="jsSuccessTips"><h1>成功提交</h1><div class="close jsCloseDialog"><img src="/static/images/dig_close.png"/></div><div class="cont"><h2>您的需求提交成功!</h2><p></p></div>
</div>
<div class="resetpassbox dialogbox" id="jsSetNewPwd"><h1>重新设置密码</h1><div class="close jsCloseDialog"><img src="/static/images/dig_close.png"/></div><p class="green">请输入新密码</p><form id="jsSetNewPwdForm"><div class="box"><span class="word2">密&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;码</span><input type="password" name="password" id="jsResetPwd" placeholder="请输入新密码"/></div><div class="box"><span class="word2">确&nbsp;认&nbsp;密&nbsp;码</span><input type="password" name="password2" id="jsResetPwd2" placeholder="请再次输入新密码"/></div><div class="box"><span class="word2">验&nbsp;&nbsp;证&nbsp;&nbsp;码</span><input type="text" name="code" id="jsResetCode" placeholder="请输入手机验证码"/></div><div class="error btns" id="jsSetNewPwdTips"></div><div class="button"><input type="hidden" name="mobile" id="jsInpResetMobil"/><input id="jsSetNewPwdBtn" type="button" value="提交"/></div></form>
</div>
<div class="bg" id="dialogBg"></div>
<header><div class="c-box fff-box"><div class="wp header-box"><p class="fl hd-tips">慕学网,在线学习平台!</p><ul class="fr hd-bar"><li>服务电话:<span>33333333</span></li><li><a href="{% url 'login' %}">[登录]</a></li><li class="active"><a href="/forgetpwd/">[忘记密码]</a></li></ul></div></div>
</header>
<section><div class="c-box bg-box"><div class="login-box clearfix"><div class="hd-login clearfix"><a class="index-logo" href="{% url 'index' %}"></a><h1>忘记密码</h1><a class="index-font" href="{% url 'index' %}">回到首页</a></div><div class="fl slide"><div class="imgslide"><ul class="imgs"><li><a href=""><img width="483" height="472" src="/static/images/57a801860001c34b12000460.jpg"/></a></li><li><a href=""><img width="483" height="472" src="/static/images/57a801860001c34b12000460.jpg"/></a></li><li><a href=""><img width="483" height="472" src="/static/images/57a801860001c34b12000460.jpg"/></a></li></ul></div><div class="unslider-arrow prev"></div><div class="unslider-arrow next"></div></div><div class="fl form-box"><h2>忘记密码</h2><form id="jsFindPwdForm" method="post" autocomplete="off">{% csrf_token %}<div class="form-group marb20 {% if forget_pwd_form.errors.email.0 %} errorput {% endif %}"><label>帐&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;号</label><input type="text" id="account" name="email" {% if message.status %} value="{{ forget_pwd_form.email.value }}" {% endif %} placeholder="请输入邮箱号"/></div><div class="form-group captcha1 marb38 {% if forget_pwd_form.errors.captchal.0 %} errorput {% endif %}"><label>验&nbsp;证&nbsp;码</label>{{ forget_pwd_form.captcha }}</div><div class="error btns" id="jsForgetTips">{{ message.msg }}</div><input type="hidden" name="sms_type" value="1"><input class="btn btn-green" id="jsFindPwdBtn" type="submit" value="提交"/><p class="form-p" style="bottom:40px;">您还可以<a href="{% url 'login' %}"> [直接登录]</a></p></form></div></div></div>
</section><input id="isLogin" type="hidden" value="False"/>
<script src="/static/js/jquery.min.js" type="text/javascript"></script>
<script src="/static/js/unslider.js" type="text/javascript"></script>
<script src="/static/js/validateDialog.js" type="text/javascript"></script>
<script src="/static/js/login.js" type="text/javascript"></script>
</body>
</html>

forgetpwd.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>{% if email_send_success %}<p>【注册账号激活】邮件已发送,请移步邮箱:{{ user_name }} 中查收!</p>{% else %}<p>【密码重置】邮件已发送,请移步邮箱:{{ email }} 中查收!</p>{% endif %}</body>
</html>

send_email_success.html

  5)email_send

   【密码重置】发送邮件的相关代码与用户注册账号激活整合在一起,详见用户注册账号激活 --发送邮件


 3.4.2 重置密码

  1)forms.py:

class ModifyPwdForm(forms.Form):"""重置密码"""password1 = forms.CharField(required=True, min_length=6)password2 = forms.CharField(required=True, min_length=6)def clean_password1(self):if self.cleaned_data.get('password1').isdigit() or self.cleaned_data.get('password1').isalpha():raise ValidationError('密码必须包含数字和字母')else:return self.cleaned_data['password1']

  2)views.py:

# 确定当前用户邮箱是否正确,如正确转到重置密码页面,进行密码重置def pwd_reset(request,ac_code):"""用户重置密码链接"""if request.method =="GET":records = EmailVerifyRecord.objects.filter(code=ac_code)if records:email = records[0].emailreturn render(request, "password_reset.html", {"email": email})else:# 链接不对return render(request, "active_fail.html")

# 重置密码def modify_pwd(request):"""重置密码"""if request.method == "POST":modify_form = forms.ModifyPwdForm(request.POST)if modify_form.is_valid():pwd1 = request.POST.get("password1", None)pwd2 = request.POST.get("password2", None)# email数据是从pwd_reset获取到的email = request.POST.get("email", None)if pwd1 != pwd2:return render(request, "password_reset.html", {"email": email, "msg": "密码不一致!"})user = UserProfile.objects.get(email=email)user.password = make_password(pwd2)user.save()return render(request, "login.html")else:email = request.POST.get("email", None)return render(request, "password_reset.html", {"email": email, "modify_form": modify_form})else:return render(request, 'password_reset.html')

  3)urls.py配置

from django.urls import path
from web_online import viewsurlpatterns = [re_path(r'^reset/(\w+)/',views.pwd_reset,name='reset'), # 邮箱重置密码链接path('modify_pwd/',views.modify_pwd,name='modify_pwd'), # 重置密码

]

  4)HTML前端代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="renderer" content="webkit"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"><title>密码修改</title><link rel="stylesheet" type="text/css" href="/static/css/reset.css"><link rel="stylesheet" type="text/css" href="/static/css/animate.css"><link rel="stylesheet" type="text/css" href="/static/css/style.css"><body>
<div class="wp"><div class="resetpassword" id="resetPwdForm"><h1>修改密码</h1><p>已经通过验证,请设置新密码</p><form id="reset_password_form" action="{% url 'modify_pwd' %}" method="post">{% csrf_token %}<ul><li class="{% if modify_form.errors.password1.0 %} errorput {% endif %}"><span class="">新 密 码 :</span><input type="password" name="password1" id="pwd" placeholder="6-20位非中文字符"><i></i></li><input type="hidden" name="email" value="{{ email }}"><li class="{% if modify_form.errors.password2.0 %} errorput {% endif %}"><span class="">再次输入密码 :</span><input type="password" name="password2" id="repwd" placeholder="6-20位非中文字符"><i></i></li><div class="error btns" id="jsPasswdResetTips" style="color: red">{% for key,error in modify_form.errors.items %}{{ key }}:{{ error }}{% endfor %}{{ msg }}</div><li class="button"><input type="submit" value="提交"></li></ul></form></div><div class="resetpassword" id="reset_password_tips" style="display:none;"><h1>修改密码成功,请重新登录</h1><img class="fl" src="/static/images/check2.png"><p class="successword">已经成功修改密码,请重新登录</p></div>
</div>
</body>
</html>

password_reset.html



未完待续。。

转载于:https://www.cnblogs.com/Eric15/p/10216106.html

python相关注册登录方式相关推荐

  1. 用python写注册登录界面web_用Python实现web端用户登录和注册功能

    这篇文章主要介绍了用Python实现web端用户登录和注册功能的教程,需要的朋友可以参考下 用户管理是绝大部分Web网站都需要解决的问题.用户管理涉及到用户注册和登录. 用户注册相对简单,我们可以先通 ...

  2. 用python写注册登录_用Python实现web端用户登录和注册功能的教程

    用户管理是绝大部分Web网站都需要解决的问题.用户管理涉及到用户注册和登录. 用户注册相对简单,我们可以先通过API把用户注册这个功能实现了: _RE_MD5 = re.compile(r'^[0-9 ...

  3. python实现注册登录系统_python实现登录与注册系统

    本文实例为大家分享了python实现登录与注册系统的具体代码,供大家参考,具体内容如下 实现功能 1.调用文本文件里的用户信息 2.可以将注册信息存储在文本文件里 3.实现了密码格式的限制 具体用户信 ...

  4. 用python写注册登录_如何用python 写注册,登录功能的测试

    2015-07-09 回答 有些网页需要你登录之后才可以访问,你需要提供账户和密码. 只要在发送http请求时,带上含有正常登陆的cookie就可以了. 1.首先我们要先了解cookie的工作原理. ...

  5. python实现注册登录检验系统的源代码_Django自带的用户验证系统实现

    首先,我要说明一下,下面内容不是必须品,如果各位大神喜欢手写也是可以的,你也可以选择自带的功能来缩减你的代码量,提高效率! 第一步 系统配置用户表 首先,在models中创建用户表,导包 from d ...

  6. python注册系统_Python制作简易注册登录系统

    Python制作简易注册登录系统 这篇文章主要为大家详细介绍了 Python 简易注册登录系统的制作方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 Python 是一种面向对象.解释型计算机程 ...

  7. Python(18)——Django实战1之可重用注册登录系统(从面到点剖析)

    文章目录 前言 0.项目开始前的思考 1.搭建项目环境(和上一篇文章一样) 1.1 创建Django项目 1.2 创建app 1.3 设置时区(中文显示) 1.4 数据库表生成 1.5 启动开发服务器 ...

  8. python学习第八天---用Django框架创建可重用注册登录系统

    python学习第八天---用Django框架创建可重用注册登录系统 实现的功能 项目开始前的整体规划 搭建环境完成基础配置 创建app 更改语言和时区 数据库表生成 启动开发服务器 浏览器访问,检测 ...

  9. python django 快速实现注册,登录,注销

    临近年底,各种忙,好久没更新博客了,2017春节假期在即,距下班还有2小时,难得闲下来,来撸一手django简单的web注册,登录,注销. 环   境:centos 6.4 64bit python ...

最新文章

  1. 面向切面编程-日志切面应用
  2. tar:文件打包归档
  3. js中的局部变量和全局变量
  4. sql concat函数_使用SQL Plus(+)和SQL CONCAT函数SQL Server CONCATENATE操作
  5. Oracle iops升高查看,一则简单的磁盘的iops测试
  6. [zz]为小米创建虚拟机路由器
  7. rust工作台可以拾取吗_10台铝型材工作台一周交货可以吗
  8. 梅创社c语言课本答案解析,c语言程序设计第2版) 教学课件 作者 梅创社答案 第一章答案.docx...
  9. Linux libaio 实例,linux libaio安装
  10. 如何用计算机算回归方程,简单线性回归方程与在线计算器_三贝计算网_23bei.com...
  11. 时间序列学习(1):平稳性、自相关性
  12. aspose-cells-8.52问题记录,excel转pdf,字体,格式
  13. APP支持请回复相关主题帖或邮件至 developer.haipeng.zhao@gmail.com
  14. 艾永亮:只要改变这两点,传统健身房行业可以逃离浩沙死咒
  15. 51单片机、STM32中生成QRCode二维码
  16. size_t、ssize_t、int、long的比较
  17. revit二次开发之数据库的使用
  18. 做人的十三条黄金玉律
  19. Python项目:外星人入侵(汇总)
  20. 使用AirCrack破解wifi密码(wpa/wpa2)

热门文章

  1. 武汉人才服务中心---迁移户口回老家---流程
  2. oracle ALTER 用法
  3. matlab遍历矩阵(读取矩阵每一个数据)
  4. mysql之sql语法
  5. 关于电商中复杂促销手段的一个解决思路-规则表达式
  6. 航拍车辆旋转框定位以及航向检测
  7. gracefully cancel/shutdown the thread
  8. 低功耗单导联心电监护模块测试说明
  9. qt中ui的 使用介绍
  10. SAPMM没有收货就可以预制发票或可以预制大于收货数量的发票