Django项目学习之用户登录登出

1.分析

业务处理流程:

  • 判断用户输入的账号是否为空
  • 判断用户输入的密码是否为空,格式是否正确
  • 判断用户输入的账号与密码是否正确

请求方法POST

url定义/user/login/

请求参数:url路径参数

参数类型前端是否必须传描述
user_account字符串用户输入的账号可以是手机号也可以是用户名
password字符串用户输入的密码
remember_me字符串用户输入的“是否记住我”

注:由于是post请求,在向后端发起请求时,需要附带csrf token


写js和写后端,其实和前面写注册用户名,发送验证码得流程差不多,下面再提几点与前面不同得需要注意的点就行。

首先是remember me功能。
在这里插入图片描述

在后台拿到数据之后,就可以开始进行验证,这里我们可以除了可以使用类似于写注册视图那样的验证之外,还可以使用django自带的form表单验证。

首先前部分写login视图,简单参数验证是否为空。

from users.forms import LoginForm
from django.views import View

# 登录页面
class LoginView(View):
	"""
	这里写登录页面逻辑
	"""
	def get(self, request):
		return render(request, 'users/login.html', context={
			'title': '登录页面',
		})


	def post(self,request):
		#接收前端传入的参数
		data = request.body
		if not data:
			return res_json(errno=Code.PARAMERR, errmsg=error_map[Code.PARAMERR])

		data = json.loads(data.decode())
		# 利用form表单进行验证
		# 
		form_login = LoginForm(data=data, request=request)
		# 以下信息在调试的时候,可以看得到
		# is_authenticated  #翻译:已验证的.已登录返回true,未登录返回false   #is_anonymous  #翻译:匿名的
		if form_login.is_valid():
			# 用户信息验证成功,使用login方法登录
			# authenticate方法验证给出的username和password是否是一个有效用户。如果有效,则返回一个User对象,无效则返回None
			user = authenticate(username=data['user_account'], password=data['password'])
			login(request, user )
			return res_json(errno=Code.OK, errmsg=error_map[Code.OK])
		else:
			return res_json(errno=Code.LOGINERR,errmsg=error_map[Code.LOGINERR])

在forms.py文件下:

# -* coding: utf-8 -*-
import re

from django import forms
from django.contrib.auth import login

from .models import Users
from django.db.models import Q
from . import constants


class LoginForm(forms.Form):
	user_account = forms.CharField()#因为用户账号可能是手机号,也有可能是用户名,在定义时不好约束,这里可以空着
	password = forms.CharField(max_length=20, min_length=6,
	                           error_messages={
		                           'min_length': '密码长度大于6',
		                           'max_length': '密码长度小于20',
		                           'required': '密码不能为空',
	                           })
	remember = forms.BooleanField(required=False)


	def __init__(self, *args, **kwargs):
		# 在传入request之后,获取到里面的值之后,request就没什么用了,可以删除掉。
		# 而pop就是删除指定字典里面指定的键,然后返回其值。
		self.request = kwargs.pop('request')
		# 下面这句是引用原来__init__的意思。因为实例化对象时加入了request参数。而原本
		# 的__init__里面是没有request参数的。这里取到request参数之后,
		# 再调用原来的__init__实例化对象
		super().__init__(*args, **kwargs)


	#这里验证用户名用的是clean方法,而前面的用户名定义为user_account,这里需要在clean之后加下划线,
	# 再加user_account。clean方法是,想要验证哪一个参数,只要在那个参数下前加下划线,然后拼接clean,
	# 成为验证那一个参数的方法的名字。
	# 这里的user_account和password字段必须和前台传过来的数据的键对应,想验证哪个键的值,就对应写clean_键
	def clean_user_account(self):
		user_info = self.cleaned_data.get('user_account')
		if not user_info:
			raise forms.ValidationError('用户名不能为空!')

		if not re.match('^1[3-9]\d{9}$', user_info) and not re.match('[\u4e00-\u9fa5\w]{5,20}', user_info):
			raise forms.ValidationError('输入的用户名格式错误,请重新输入!')
		return user_info

	def clean_password(self):
		password = self.cleaned_data.get('password')
		if not password:
			raise forms.ValidationError('密码不能为空')

		return password


	# 重写clean方法,针对参数进行验证
	def clean(self):
		# 使用父类的clean方法
		cleaned_data = super().clean()
		user_info = cleaned_data.get('user_account')
		pass_pwd = cleaned_data.get('password')
		rmber = cleaned_data['remember']

		# Q方法是“或”的意思
		user_qs = Users.objects.filter(Q(mobile=user_info) | Q(username=user_info))

		if user_qs:
			# .first是返回第一个对象
			user = user_qs.first()
			# 判断密码,check_password是django的auth系统自带的check_password方法
			# 不能直接取出密码对比,因为密码在django写入mysql时已经进行加密,得利用它自己的
			# 方法验证。
			# 设置密码也有自带方法。
			if user.check_password(pass_pwd):
				if rmber:
					self.request.session.set_expiry(constants.SESSION_EXPIRY_TIME)
				else:
					self.request.session.set_expiry(constants.SESSION_TIME)
				# login(self.request, user_info)
			else:
				raise forms.ValidationError('用户名或密码错误!')
		else:
			raise forms.ValidationError('用户名不存在,请重新输入!')
		return cleaned_data

如果想在html文件中设置什么,需要什么条件的话,在调试的时候,可以看到它返回一个user对象,里面有许多参数,在利用模板时,可以使用上,如:

        <div class="login-box">
            {% if not user.is_authenticated %}
                <div>
                    <i class="PyWhich py-user"></i>
                    <span>
                      <a href="{% url 'users:login' %}" class="login">登录</a> / <a href="{% url 'users:register' %}" class="reg">注册</a>
                    </span>
                </div>
            {% else%}
            <div class="author">
                <img class='img_icon' src="/static/img/浪浪.jpg">
                <span class="user_name">{{ user.username }}</span>
{#                <span>#}
                <ul class="author-menu">
                    {% if user.is_staff %}
                    <li class="back_stage"><a href="javascript:void(0);">后台管理</a></li>
                    {% endif %}
                    <li class="logout"><a href="javascript:void(0);">退出登录</a></li>
                </ul>
{#                </span>#}
            </div>
            {% endif %}
        </div>

而登出则更简单,使用django自带的logout方法,只需把request传进去即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值