登陆模块——逻辑总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wzyaiwl/article/details/89421531

登陆模块在后端需要接收三个参数,分别是账号、密码、是否记住标志。为了实现这个三个参数的正确,需要给这三个参数写一个form,并在里面实现各个验证逻辑。记住和不记住的区别在于session的保存有效期,不记住就将session设置为0,即浏览器关闭就失效,记住标志可以将session有效期设为一个礼拜或两个礼拜都行。

在前端页面,可以使用模板语言,将用户是否登陆的状态,给予其不同的页面展示,对于该用户是否拥有管理后台权限,同等如此。

登陆验证api

1、接收前端传来的参数,用户名、电话、密码、确认密码、短信验证码
2、form表单的构造,并实现相应的验证逻辑
3、验证成功后,将用户名、密码、电话保存在数据库中,用到用户模型的creat_user方法
4、注册成功后,自动跳转到已登陆状态
  • form表单
class Login_form(forms.Form):
    user_account = forms.CharField(max_length=20,min_length=5,required=True)
    password = forms.CharField(max_length=20,min_length=6,required=True,error_messages={
        'max_length':'密码长度不能低于6位','min_length':'密码名长度不能大于20位','required':'密码不能为空'
    })
    remember_me = forms.BooleanField(required=False)

    def __init__(self, *args, **kwargs):
        """
        """
        self.request = kwargs.pop('request', None)
        super().__init__(*args, **kwargs)

    def clean_user_account(self):
        user_acc = self.cleaned_data.get('user_account')
        if not user_acc:
            raise forms.ValidationError('账号不能为空')
        if not re.match('^1[3-9]/d{9}$',user_acc) and (len(user_acc)<5 or len(user_acc)>20):
            raise forms.ValidationError("账号不符合格式")
        return user_acc
    def clean(self):
        cleaned_data = super().clean()
        user_info = cleaned_data.get('user_account')
        passwd = cleaned_data.get('password')
        holded_login = cleaned_data.get('remember_me')

        user_queryset = Users.objects.filter(Q(mobile = user_info)|Q(username = user_info))
        if not user_queryset.first():
            raise forms.ValidationError("此账号不存在,请重新输入")
        else:
            user = user_queryset.first()
            if user.check_password(passwd):
                if holded_login:
                    self.request.session.set_expiry(60*15*24*60)
                else:
                    self.request.session.set_expiry(0)
                login(self.request,user)
            else:
                raise forms.ValidationError("密码不正确,请重新输入")
  • 视图函数
class Register(View):
    """
    """
    def get(self,request):
        return render(request, 'users/register.html')
    def post(self,request):
        json_data = request.body
        if not json_data:
            return to_json_data(errno= Code.PARAMERR,errmsg=error_map[Code.PARAMERR])
        dict_data = json.loads(json_data.decode('utf-8'))
        form = User_form(data=dict_data)
        if form.is_valid():
            #将用户名、密码保存到数据库中
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            mobile = form.cleaned_data.get('mobile')
            user = Users.objects.create_user(username=username,password=password,mobile=mobile)
            user.save()
            login(request, user)
            return to_json_data(errmsg="恭喜您,注册成功!")
        else:
            error_list = []
            for item in form.errors.get_json_data().values():
                # error_list = error_list.append(item[0].get('message'))
                error_list.append(item[0].get('message'))
            err_msg_str = '/'.join(error_list)  # 拼接错误信息为一个字符串
            return to_json_data(errno=Code.PARAMERR, errmsg=err_msg_str)
  • 路由设置
urlpatterns = [
        path('login/',views.Login.as_view(),name='login'),
]
  • Ajax部分代码
 let SdataParams = {
      "user_account": sUserAccount,
      "password": sPassword,
      "remember_me": bStatus
    };

    // 创建ajax请求
    $.ajax({
      // 请求地址
      url: "/users/login/",  // url尾部需要添加/
      // 请求方式
      type: "POST",
      data: JSON.stringify(SdataParams),
      // 请求内容的数据类型(前端发给后端的格式)
      contentType: "application/json; charset=utf-8",
      // 响应数据的格式(后端返回给前端的格式)
      dataType: "json",
    })
      .done(function (res) {
        if (res.errno === "0") {
          // 注册成功
          message.showSuccess('恭喜你,登录成功!');
          setTimeout(function () {
            // 注册成功之后重定向到打开登录页面之前的页面
            window.location.href = document.referrer;
          }, 1000)
        } else {
          // 登录失败,打印错误信息
          message.showError(res.errmsg);
        }
      })
      .fail(function(){
        message.showError('服务器超时,请重试!');
      });
  • 踩坑记录:
    ​​1、form表单的request从哪里来?可以在视图调用form表单传参过去,form表单在__init__方法里进行接收
    2、login方法登陆传入的两个参数request和user是位置参数,不是默认参数。
    

​​​​​​​登出api

登出api实现对现有用户session的清除。

1、对于登陆,注册接口是否展示,取决于当前是否登陆if user.is_authenticated
2、对于隐藏的后台管理接口是否展示,取决于当前用户是否有登陆的后台的权限user.is_staff
3、对于登出功能是否展示,取决于当前是否有用户已经登陆if user.is_authenticated
4、当前用户名展示{{ user.username }}
  • 视图函数
class Login_out(View):
    """
    """
    def get(self,request):
        logout(request)
        return redirect(reverse('users:login'))
  • 路由设置

urlpatterns = [
        path('loginout/',views.Login_out.as_view(),name='log_out'),
        ]

猜你喜欢

转载自blog.csdn.net/wzyaiwl/article/details/89421531