zoukankan      html  css  js  c++  java
  • day57 Django补充内容(中间件其他方法、jQuery操作cookie、csrf详解和form组件简单使用)

    day57 Django补充内容(中间件其他方法、jQuery操作cookie、csrf详解和form组件简单使用)

    中间件其他方法

    我们已经学到了中间件的三个方法:process_request、process_respond 和 process_view:

    • process_request 在路由分发之前被调用,用来处理请求的数据;

    • process_respond 在gwsi相应之前进行一些处理;

    • process_view 在路由分发之后,进入视图函数之前执行。

    此外,中间件还有两个方法,process_exception 和 porcess_remplate_response:

    • process_exception 是当试图出现异常时执行,如果没有出现异常则不执行;
    • process_template_response 只对重写了响应对象中 render 方法的相应有作用。

    其基本用法为:

    from django.shortcuts import redirect,HttpResponse,render
    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
    
        def process_request(self,request):
            print('MD1--process_request')
            
        def process_response(self, request,response):
            print('MD1--process_response')
            return response
            
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('MD1---',view_func.__name__)
    
        # 视图有错误,执行中间件的process_exception方法,没错不执行
        def process_exception(self, request, exception):
            print('MD1:process_exception',exception)
    
        def process_template_response(self, request, response):
            print("MD1 中的process_template_response")
            return response
    
    
    class MD2(MiddlewareMixin):
    
        def process_request(self, request):
            print('MD2--process_request')
    
        def process_response(self, request, response):
            print('MD2--process_response')
            return response
        def process_view(self, request, view_func, view_args, view_kwargs):
            print('MD2---',view_func.__name__)
    
        def process_exception(self, request, exception):
            print('MD2:process_exception',exception)
    
        def process_template_response(self, request, response):
            print("MD2 中的process_template_response")
            return response
    

    重写响应对象中render方法的示例:

    def index(request):
    
        def render():
            print('index函数内部的render')
            return HttpResponse('xxxx')
    
        ret = HttpResponse('ok')
        ret.render = render
        return ret
    

    中间件的执行顺序大致是这样的:

    1575286071120

    Django 请求的生命周期

    1575292152675

    ajax通过csrf的第三种方式

    $('#btn').click(function () {
    
        var uname = $('[type="text"]').val();
        var pwd = $('[type="password"]').val();
        var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
    
        $.ajax({
            url:'/login/',
            type:'post',
            // data:{uname:uname,pwd:pwd,csrfmiddlewaretoken:csrf_token},
            headers:{'X-CSRFToken':$.cookie('csrftoken')}, // 设置请求头:
            data:{uname:uname,pwd:pwd,},
            success:function (res) {
            	console.log(res);
            }
        })
    })
    

    csrf

    CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者通过 HTTP 请求江数据传送到服务器,从而盗取回话的 cookie。盗取回话 cookie 之后,攻击者不仅可以获取用户的信息,还可以修改该 cookie 关联的账户信息。

    所以解决 CSRF 攻击的最直接的办法就是生成一个随机的 csrftoken 值,保存在用户的页面上,每次请求都带着这个值过来完成校验。

    jquery设置cookie

    $('#btn').click(function () {
    
            var uname = $('[type="text"]').val();
            var pwd = $('[type="password"]').val();
            var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
    
            $.cookie('xx','sss'); // 设置cookie
    
            $.ajax({
                url:'/login/',
                type:'post',
                // data:{uname:uname,pwd:pwd,csrfmiddlewaretoken:csrf_token},
                headers:{'X-CSRFToken':$.cookie('csrftoken')},
                data:{uname:uname,pwd:pwd,},
    
                success:function (res) {
                    console.log(res);
                }
            })
        })
    

    form组件

    form 组件主要有三个用途:

    1. 生成页面可用的HTML标签
    2. 对用户提交的数据进行校验
    3. 保留上次输入内容

    使用步骤:

    1 创建form类

    from django import forms
    
    class LoginForm(forms.Form):
        # username = request.POST.get('username')
        # if '--' in username:
        #     raise
        # {'username':'xxxx','password':''}
        username = forms.CharField(
            label='用户名:',
            required=True,  #不 能为空
            max_length=7, # 长度不能超过7个字符
            min_length=2, # 最短不能低于2个字符
            # initial='张三', #初始值
            widget=forms.TextInput(attrs={'class':'c1','placeholder':'请输入用户名'}),
            error_messages={
                'required':'不能为空',
                'max_length':'太长了,难受!',
                'min_length':'太短了,更难受!',
            },
        )
    
        password = forms.CharField(
            required=True,
            label='密码:',
            widget=forms.PasswordInput(attrs={'class':'c1','placeholder':'请输入密码'},render_value=True), # render_value=True让密码输入的数据保留
    
        )
    
        sex = forms.ChoiceField(
            choices=[(1,'男'),(2,'女')],
            widget=forms.RadioSelect(attrs={'xx':'none'}),
    
        )
    

    2 在views中实例化这个类对象,并交给前端 html 页面

    def login(request):
        if request.method == 'GET':
            form_obj = LoginForm()
    
            return render(request,'login.html', {'form_obj':form_obj})
        else:
            form_obj = LoginForm(request.POST)
            # 准备校验,也就是检查不符合格式的部分,并且保存到列表中,写成伪代码为:
            # form_obj
            # username:alexxxxxx -- form_obj.username.errors.append('太长了!!')
            # username:alexxxxxx -- form_obj.username.errors.append('包含了--!feifa zifu')
            # password  form_obj.password.errors.append('太长了!!')
            print(status)
    
            return render(request,'login.html', {'form_obj':form_obj})
    

    3 进行数据格式校验

    form_obj = LoginForm(request.POST)
    status = form_obj.is_valid() # 开始校验,上面的伪代码Django已经封装好,直接使用即可
    print(status)
    
    return render(request,'login.html', {'form_obj':form_obj})
    

    在前端页面中,可以写成这样:

    <form action="" method="post" novalidate>
        {% csrf_token %}
        <div>
            <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
            {{ form_obj.username }}
            <span>{{ form_obj.username.errors.0 }}</span>
        </div>
        <div>
            <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
            {{ form_obj.password }}
            <span>{{ form_obj.password.errors.0 }}</span>
        </div>
        <input type="submit">
        
        <div>
            <label for="{{ form_obj.sex.id_for_label }}">{{ form_obj.sex.label }}</label>
            {{ form_obj.sex }}
        </div>
    </form>
    
  • 相关阅读:
    TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常?
    当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
    @Qualifier 注解?
    Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?是用==还是equals()?它们有何区别?
    Filter是什么?有什么作用?
    List和 Map区别?
    Spring框架的事务管理有哪些优点?
    Listener是什么?有什么作用?
    字节流与字符流的区别?
    Struts2里面有什么隐式对象?
  • 原文地址:https://www.cnblogs.com/shuoliuchina/p/11973283.html
Copyright © 2011-2022 走看看