zoukankan      html  css  js  c++  java
  • Django中间件 及 form 实现用户登陆

    Django中间件 及 form 实现用户登陆

    • Form 验证

    • 密码调用md5 加密存储

    • form.add_error("字段名", "错误信息") 自定义错误信息

    • 装饰器实现 用户认证

    • 中间件实现 用户认证

        中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能。
      

    django默认的中间件在settings.py中

         当用户发起请求的时候会依次经过所有的的中间件,这个时候的请求时process_request,最后到达views的函数中,views函数处理后,在依次穿过中间件,这个时候是process_response,最后返回给请求者。
    

    中间件MIDDLEWARE

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    

    自定义中间件

        自己定义一个中间件,写一个类,但是必须继承MiddlewareMixin     
    

    中间件分为五种方法:

    process_request(self,request)                        ***** 用于请求时过滤
    process_response(self, request, response)            ***** 用于相应时过滤 必须有返回值
    process_view(self, request, callback, callback_args, callback_kwargs)     *** 在执行完所有的process_request 后在回到 起点执行process_view ,然后在执行 视图函数
    process_exception(self, request, exception)          ***   对异常信息捕捉
    process_template_response(self,request,response)     *     视图函数返回的对象中间有render方法,就会被触发
    

    中间件

    创建middlwares模块

    定义中间件包

    1.md.py内容中间件值

    from django.conf import settings
    from django.shortcuts import redirect
    
    
    # 该 MiddlewareMixin 类为默认继承类,在Django 1.10 之后需要该类的继承,1.7-1.8 无需该类继承
    class MiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    class M1(MiddlewareMixin):
        # process_request 用于请求时过滤 判断有没有 USER_SESSION_KEY 
        def process_request(self, request, *args, **kwargs):
    
            # path_info 获取当前URL 的路径值,不带参数的路径
            # 如果Url 为 login 就返回一个None 让请求继续
            if request.path_info == "/login/":
                return None
            else:
                user_info = request.session.get(settings.USER_SESSION_KEY)
                if not user_info:
                    return redirect("/login/")
                    
        # 如果页面出现错误,将请求返回给/index/页面(可以将错误信息记录日志)                
        def process_exception(self,request,exception):
            print("=========",exception)
            return redirect("/index/")
        
        # 用于相应时过滤 必须有返回值
        def process_response(self, request, response):
            print("m1.process_response")
            return response
    

    2.在settings.py中引用该中间件

    # 中间件配置
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        "middlwares.md.M1",            # 指定自定义中间件 位置
    ]
    
    # SESSION 的别名
    USER_SESSION_KEY = "user_info_key"
    

    3.在views.py 中设置值

    from django.shortcuts import render, redirect, HttpResponse
    
    # Create your views here.
    from app01.forms import LoginForm
    
    from app01 import models
    from django.conf import settings    # 用户自定义 + 内置的 settings 配置文件
    from utils.md5 import md5           # utils 为自定义工具 包
    
    
    def login(request):
        if request.method == "GET":
            form = LoginForm()
            return render(request, "login.html", {"form": form})
    
        else:
            # 将接收到的数据,传给LoginForm()类 通过form 验证;
            form = LoginForm(request.POST)
            # 通过 form 验证后,form 为True
            if form.is_valid():
                # 通过form验证的数据 存放在 cleaned_data 中
                # form.cleaned_data
    
                form.cleaned_data["password"] = md5(form.cleaned_data["password"])
    
                # 通过 **form.cleaned_data 可以将 数据依照字典形式获取 filter({"username":zhangsan,"password":1234})
                userinfo = models.UserInfo.objects.filter(**form.cleaned_data).first()  # 拿取第一个对象值
    
                # 如果userinfo 中有数据,即表示验证成功
                if userinfo:
                    # 将 用户信息 放置到 session 中
                    request.session[settings.USER_SESSION_KEY] = {"id": userinfo.pk, "username": userinfo.username}
    
                    # 重定向 页面
                    return redirect("/index/")
                else:
                    # 用户验证失败,password 错误信息显示在哪个 字段上
                    form.add_error("password", "用户名或密码错误")
    
            # 存放错误信息 form.errors
    
            # 将 form 清洗过的 数据直接返回给 html 模板
            return render(request, "login.html", {"form": form})
    
    
    def index(request):
        return HttpResponse("验证成功!")
        # return render(request, "index.html")
    

    4.定义工具模块md5.py

    import hashlib
    
    def md5(text):
        m = hashlib.md5()
        m.update(text.encode("utf-8"))
        return m.hexdigest()
    
    if __name__ == '__main__':
        text = "zhangsan"
        print(md5(text))
    

    5.forms.py 验证配置

    from django.forms import Form
    
    # widgets 表示插件
    from django.forms import widgets
    
    # fields 表示所有的字段
    from django.forms import fields
    
    
    class LoginForm(Form):
        username = fields.CharField(
            label="用户名",
            required=True,       # 表示不能为空,默认不可为空
            error_messages={     # 错误信息 依照中文形式显示
                "required": "用户名不能为空",       # required 为真是错误信息
            },
            # 插件类型TextInput(attrs={"class": "自定义属性 多个依照空格分隔 form-control 为bootcss属性"})
            widget=widgets.TextInput(attrs={"class": "form-control xxx aaa"})
        )
    
        password = fields.CharField(
            label="密码",
            required=True,       # 表示不能为空,默认不可为空
            error_messages={     # 错误信息 依照中文形式显示
                "required": "密码不能为空",       # required 为真是错误信息
            },
            widget=widgets.PasswordInput(attrs={"class": "form-control"})
        )
    
  • 相关阅读:
    Xcode 10 storyBoard中控件区域位置修改
    使用WeexSDK,网络请求信任证书的问题
    真机调试包,解决xcode跑不了高版本iOS系统问题,及Deployment Target不显示高版本系统的问题
    vim进阶学习
    Linux中的inode(转载)
    Linux的文件权限
    远程连接Linux服务器
    WinSDK绘制文本
    (转载)Win32 SDK编程系列文章——菜单(快捷菜单)——动态加载
    (转载)Windows Socket五种I/O模型——代码全攻略
  • 原文地址:https://www.cnblogs.com/baolin2200/p/8157595.html
Copyright © 2011-2022 走看看