美文网首页
Django自定义用户登陆相关

Django自定义用户登陆相关

作者: 镜kong | 来源:发表于2017-11-30 20:36 被阅读0次

    虽说有 django-allauth 这个很好用的轮子在,但是自己造个轮子更能加深对DJango的理解,也更灵活下面记录一下 Django用户登陆,注册等自定义实现的知识。

    用户登陆

    • 函数实现方式
    from django.contrib.auth import authenticate, login
    
    def user_login(request):
        if request.method == "POST":    
            user_name = request.POST.get("username", "")  # 获取form传递过来的POST中的参数 默认值为空
            pass_word = request.POST.get("password", "")
            user = authenticate(username=user_name, password=pass_word)  #验证用户(如果验证通过会返回UserProfile对象,否则返回None)
            if user is not None:
                login(request, user)  # 登陆
                return render(request, 'index.html')
            else:
                return render(request, 'login.html')
            elif request.method == "GET":
                return render(request, 'login.html')
    
    • 类的实现方式
    from django.contrib.auth import authenticate, login
    from django.views.generic.base import View
    
    class LogView(View):
        def get(self, request):
            return render(request, 'login.html')
    
        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": "用户名或密码错误"})
    
    类和函数的区别
    • 类可以继承
    • 类下面可以写很多函数方法
      类似上面的例子其实功能性代码是一样的 只是类比函数少了一些if判断
      类通过复写 get和post方法 自动调用相关代码,相比 函数架构更好。

    自定义 authenticate

    DJango默认的 authenticate 不能做到类似 邮箱账号或手机号登陆,但是我们可以复写(重载)authenticate

    • Q 是用来实现 或| 的
    # 任意views中插入如下代码
    from django.contrib.auth.backends import ModelBackend
    from .models import UserProfile 
    from django.db.models import Q
    
    class CustomBackend(ModelBackend):
        def authenticate(self, username=None, password=None, **kwargs):
            try:
                user = UserProfile.objects.get(Q(username=username)|Q(email=username))  # 同理还可以加一个 |Q(iphone=username)
                if user.check_password(password):
                    return user
            except Exception as e:
                return None
    
    
    # setting.py  项目setting.py中插入如下 users就是上述代码插入的app.views
    
    # Application definition
    AUTHENTICATION_BACKENDS = (
        'users.views.CustomBackend',
    )
    

    使用form验证

    form 表单是 Web开发很重要的一个组件
    在用户登陆这个动作中 使用 form 可以提前对数据进行验证,比如非空,字符串长度等等,直接在 前端就对数据进行了验证,减少了对数据库的压力。

    • 在 app 中 新建一个 forms.py
    from django import forms
    
    class LoginForm(forms.Form):
        username = forms.CharField(required=True)  #验证非空
        password = forms.CharField(required=True, min_length=5)  #验证非空,字符串不小于5
    
    # views.py
    from .forms import LoginForm #导入新建的form类
    
    class LoginView(View):
        def get(self, request):
            return render(request, "login.html", {})
        def post(self, request):
            login_form = LoginForm(request.POST)  #实例化form对象传入POST数据 会自动去验证POST中的同名参数(username password)
            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})
    

    将 form 的错误信息返回到前端

    form 验证失败后会返回一个 errordict


    image.png

    要将这个错误信息显示到前端只需要将 返回的 login_form 对象传递到 temple 中


    image.png
    再像上面这个 输出 error
    image.png

    相关文章

      网友评论

          本文标题:Django自定义用户登陆相关

          本文链接:https://www.haomeiwen.com/subject/tejbbxtx.html