搜索
简帛阁>技术文章>Django项目(电商) 第四节 用户登录 笔记

Django项目(电商) 第四节 用户登录 笔记

用户名登陆

用户名登陆逻辑分析

用户名登录接口设计

请求方式

选项方案
请求方法POST
请求地址/login/
请求参数:表单参数
参数名类型是否必传说明
usernamestring用户名
passwordstring密码
rememberedstring是否记住用户

响应结果:HTML

响应结果相应内容
登陆失败相应错误提示
登陆成功重定向到首页

用户名登陆接口定义

class LoginView(View):
    '''用户名登陆'''
    def get(self,request):
        

        return render(request,'login.html')
    def post(self,request):
        pass

用户登录后端逻辑

class LoginView(View):
    '''用户名登陆'''
    def get(self,request):


        return render(request,'login.html')
    def post(self,request):
        login_form=LoginForm(request.POST)
        if login_form.is_valid():
            username = login_form.cleaned_data.get('username')
            password = login_form.cleaned_data.get('password')
            #如果没有用form表单验证的话,不能用login_form.cleaned_data
            remembered = request.POST.get('remembered')
            #认证登陆用户
            # users = User.objects.get(username=username).count()
            # if users == 0:
            #     return render(request, 'login.html', {"errmsg": "该用户未注册"})
            # users.check_password(password)
            user=authenticate(username=username,password=password)
            if user is None:
                return render(request,'login.html',{"errmsg":"账号或密码错误"})

            login(request,user)
            #使用remembered保持登陆状态
            if remembered !='on':
                #如果没有记住登陆状态,状态保持的浏览器关闭
                request.session.set_expiry(0)
            else:
                #如果记住登陆状态  None默认为两周
                request.session.set_expiry(None)
            #方案一实现方法
            #return redirect(reverse('contents:index'))
            # 方案三vue实现方法
            response= redirect(reverse('contents:index'))
            response.set_cookie('username',user.username,max_age=3600*24*14)
            return response
        else:
            print(login_form.errors.get_json_data())
            context={
                'forms_errors':login_form.errors
            }
            return render(request,'login.html',context=context)

多账号登陆

  • Django自带的用户认证后端默认是使用用户名实现用户认证的

  • 用户认证后端位置:django.contrib.auth.backends.ModelBackend

  • 如果想要实现用户名和手机号都可以认证用户,就需要自定义用户认证后端

  • 自定义用户认证后端步骤
    1、在users应用中新建utils.py文件
    2、新建类,继承自ModelBackend
    3、重写认证authenticate()方法
    4、分别使用用户名和手机号查询用户
    5、返回查询到的用户实例

自定义用户认证后端
users.utils.py

from django.contrib.auth.backends import ModelBackend
import re
from users.models import User

def get_user(account):
        """
        获取user对象
        :param account: 手机号或用户名
        :return: user
        """
        try:
            if re.match(r'^1[3-9]\d{9}', account):
                user = User.objects.get(mobile=account)

            else:
                user = User.objects.get(username=account)
                
        except User.DoesNotExist:
            return None
        # 没有异常发生的时候,执行else语句
        else:
            return user

class UsernameMobileBackend(ModelBackend):
    '''自定义用户认证后端'''

    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        :param username: 用户名或手机号
        :param password: 密码明文
        :param kwargs: 额外参数
        :return: user
        """
        user = get_user(username)
        if user and user.check_password(password):
            return user
        else:
            return None

dev.py中定义自己写的方法引用路径

AUTHENTICATION_BACKENDS = ['users.utils.UsernameMobileBackend']

首页用户名展示

方案一:

  • 模板中request变量直接渲染用户名
  • 缺点:不方便做首页静态化
{% if user.is_authenticated %}
	<div>
                    欢迎您:<em>{<!-- -->{ user.username }}</em>
                    |
                    <a href="#">退出
                </div>
				{% else %}
				<div>
					|
					登录
					|
					注册
				</div>
{% endif %}

方案二:

  • 发送ajax请求获取用户信息
  • 缺点:需要发送网络请求
<div>
{# ajax渲染 #}
</div>

方案三:

  • Vue读取cookie、渲染用户信息

views.py

class LoginView(View):
   '''用户名登陆'''
   def get(self,request):


       return render(request,'login.html')
   def post(self,request):
       login_form=LoginForm(request.POST)
       if login_form.is_valid():
           username = login_form.cleaned_data.get('username')
           password = login_form.cleaned_data.get('password')
           #如果没有用form表单验证的话,不能用login_form.cleaned_data
           remembered = request.POST.get('remembered')
           #认证登陆用户
           # users = User.objects.get(username=username).count()
           # if users == 0:
           #     return render(request, 'login.html', {"errmsg": "该用户未注册"})
           # users.check_password(password)
           user=authenticate(username=username,password=password)
           if user is None:
               return render(request,'login.html',{"errmsg":"账号或密码错误"})

           login(request,user)
           #使用remembered保持登陆状态
           if remembered !='on':
               #如果没有记住登陆状态,状态保持的浏览器关闭
               request.session.set_expiry(0)
           else:
               #如果记住登陆状态  None默认为两周
               request.session.set_expiry(None)
           response=redirect(reverse('contents:index'))
           # set_cookie('key,'value','erpriy')
           response.set_cookie('username',user.username,max_age=3600*24*14)
           return  response
       else:
           print(login_form.errors.get_json_data())
           context={
               'forms_errors':login_form.errors
           }
           return render(request,'login.html',context=context)

index.js

let vm = new Vue({
    el: '#app',
    delimiters: ['[[', ']]'],
    data: {
        username: getCookie('username'),
        f1_tab: 1, // 1F 标签页控制
        f2_tab: 1, // 2F 标签页控制
        f3_tab: 1, // 3F 标签页控制

        // 渲染首页购物车数据
        cart_total_count: 0,
        carts: [],
    },
    methods: {
        // 获取简单购物车数据
        get_carts(){
            let url = '/carts/simple/';
            axios.get(url, {
                responseType: 'json',
            })
                .then(response => {
                    this.carts = response.data.cart_skus;
                    this.cart_total_count = 0;
                    for(let i=0;i<this.carts.length;i++){
                        if (this.carts[i].name.length>25){
                            this.carts[i].name = this.carts[i].name.substring(0, 25) + '...';
                        }
                        this.cart_total_count += this.carts[i].count;
                    }
                })
                .catch(error => {
                    console.log(error.response);
                })
        }
    }
});

index.html

<div>
                    欢迎您:<em>[[ username ]]</em>
                    |
                    退出
                </div>

				<div>
					|
					登录
					|
					注册
				</div>

退出登录

1、退出登录:

  • 回顾登录:将通过认证的用户的唯一标识信息,写入到当前session会话中
  • 退出登录:正好和登陆相反(清理session会话信息)

2、logout()方法:

  • Django用户认证系统提供了logout()方法
  • 封装了清理session的操作,帮助我们快速实现登出一个用户

3、logout()方法:
django.contrib.auth._init_.py文件中

logout(request)

logout()方法使用

class LogoutView(View):
	"""退出登录"""
	def get(self,request):
	"""实现退出登录逻辑"""
	#清理session
	logout(request)
	#退出登录,重定向到登陆页
	response = redirect(reverse('contents:index'))
	#退出登录时清除cookie中的username
	response.delete_cookie("username")
	return response

判断用户是否登录

展示用户中心界面

class UserInfoView(View):
	"""用户中心"""
	def get(self,request):
		"""提供个人信息界面"""
		return render(request,'user_center_info.html')

需求:

  • 当用户登陆后,才能访问用户中心
  • 如果用户未登录,就不允许访问用户中心,将用户引导到登陆页面

实现方案:

  • 需要判断用户是否登录
  • 根据是否登录的结果,决定用户是否可以访问用户中心

is_authenticate判断用户是否登录

介绍:
· Django用户认证系统提供了方法request.user.is_authenticated()来判断用户是否登录。
· 如果通过登陆验证则返回True,反之,返回False
· 缺点:登陆验证逻辑很多地方都需要,所以该代码需要重复编码好几次

class UserInfoView(View):
	"""用户中心"""
	def get(self,request):
		"""提供个人信息界面"""
        if request.user.is_authenticated:  #判断用户是否登录
            return render(request,'user_center_info.html')
        else:
            return redirect(reverse('users:login'))

login_required装饰器判断用户是否登录

· Django用户认证系统提供了装饰器login_required来判断用户是否登录
· 内部封装了is_authenticate
· 位置:django.contrib.auth.decorators

· 如果通过验证则进入试图内部,执行视图逻辑
· 如果未通过登陆验证则被重定向到LOGIN_URL配置的指定的地址
· 如下配置:表示用户未通过登陆验证时,将用户重定向到登陆页面

LOGIN_URL = 'login'

继承验证用户是否登陆扩展类

from django.contrib.auth.mixins import LoginRequiredMixin
class UserInfoView(LoginRequiredMixin,View):
    def get(self, request):
        """提供用户中心页面"""

        return render(request,'user_center_info.html')

登陆时next参数的使用

# views.py   填写在登陆类中,返回值返回


next = request.GET.get('next')
            if next:
                response=redirect(next)
            else:
                response = redirect(reverse('contents:index'))
用户名登陆用户名登陆逻辑分析用户名登录接口设计请求方式选项方案请求方法POST请求地址/login/请求参数:表单参数参数名类型是否必传说明usernamestring是用户名passwordstri
验证码图形验证码图形验证码逻辑分析·新建应用Verifications将图形验证码的文字信息保存到Redis数据库,为短信验证码做准备。UUID用于区分该图形验证码属于哪个用户,也可使用其他唯一标识信
lassLoginView(View):"""用户名登录"""defget(self,request):"""提供登录界面:paramrequest:请求对象:return:登录界面"""retur
文章目录1路由注册2接口编写21service层22api层23service3登陆测试1路由注册定义一个用户登录路由v1POST(user/login,apiUserLogin)2接口编写21ser
前言有时候Django自带的用户登录认证不能满足我们的需求,比如我不想要用户名+密码登录,我想手机号+验证码登录,这样就需要我们去修改Django自带的认证了。Django默认使用用户认证的是Mod
用户部分是一个网站的基本功能,django对这部分进行了很好的封装,我们只需要在django的基础上做些简单的修改就可以达到我们想要的效果首先我假设你对django的session、cookie和数据
Django是由Python开发的一个免费的开源网站框架,可以用于快速搭建高性能,优雅的网站!学习django学得超级吃力,最近弄个最简单的用户登录与注册界面都是那么难,目前算是基本实现了,虽然功能特
记得在app01下的models中搞定模型类建立迁移文件:pythonmanagepymakemigrations根据迁移文件在指定数据库中生成表:pythonmanagepymigratecreat
1,urlspy内容:fromdjangoconfurlsimporturlfromdjangocontribimportadminfrommyAppimportviewsurlpatterns[ur
本文实例讲述了django框架实现的用户注册、登录、退出功能。分享给大家供大家参考,具体如下:1用户注册:fromdjangocontribimportauthfromdjangocontribau