Django框架10 /sweetalert插件、django事务和锁、中间件、django请求生命周期

1. SweetAlert插件示例

  • 使用流程:

    1. 在github下载css、js文件放到项目静态文件夹中,https://github.com/LBZHK/bootstrap-sweetalert
    2. 在html页面分别引入jquery、bootstrap文件,sweetalert是基于bootstrap实现,bootstrap是基于jquery实现的
    3. 将代码复制到script标签中
  • 代码示例:

    $(".btn-danger").on("click", function () {
    swal({
    title: "你确定要删除吗?",
    text: "删除可就找不回来了哦!",
    type: "warning",
    showCancelButton: true,
    confirmButtonClass: "btn-danger",
    confirmButtonText: "删除",
    cancelButtonText: "取消",
    closeOnConfirm: false
    },
    function () {
    var deleteId = $(this).parent().parent().attr("data_id");
    // 注意:此处$(this)已经不是".btn-danger"这个点击的对象
    $.ajax({
    url: "/delete_book/",
    type: "post",
    data: {"id": deleteId},
    success: function (data) {
    if (data.status === 1) {
    swal("删除成功!", "你可以准备跑路了!", "success");
    } else {
    swal("删除失败", "你可以再尝试一下!", "error")
    }
    }
    })
    });
    })

2. django事务和锁

  • mysql

    # 锁:
    select * from book where id=1 for update; # 事务:
    begin/start trancsation # 开启事务
    select * from book where id=1 for update;
    commit # 提交
    rollback # 回滚
  • django orm的事务/锁

    models.Book.objects.select_for_update().filter(id=1)

    事务

    • 全局开启事务
    # 1.在Web应用中,常用的事务处理方式是将每个请求都包裹在一个事务中。这个功能使用起来非常简单,你只需要将它的配置项ATOMIC_REQUESTS设置为True。
    
    # 2.当有请求过来时,Django会在调用视图方法前开启一个事务。如果请求正确处理并正确返回了结果,Django就会提交该事务。否则,Django会自动回滚该事务。
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'mxshop',
    'HOST': '127.0.0.1',
    'PORT': '3306',
    'USER': 'root',
    'PASSWORD': '123',
    'OPTIONS': {
    "init_command": "SET default_storage_engine='INNODB'",
           #'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", # 配置开启严格sql模式 }
    "ATOMIC_REQUESTS": True, # 全局开启事务,绑定的是http请求响应整个过程
    "AUTOCOMMIT":False, # 全局取消自动提交,慎用
    },
      'other':{
        'ENGINE': 'django.db.backends.mysql',
    ......
      } # 还可以配置其他数据库
    }
    • 局部使用事务

    用法1:给函数做装饰器来使用

    from django.db import transaction
    
    @transaction.atomic
    def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

    用法2:作为上下文管理来使用,其实就是设置事务的保存点

    from django.db import transaction
    
    def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff() with transaction.atomic(): # 保存点
    # This code executes inside a transaction.
    do_more_stuff() do_other_stuff()

3. 中间件

  • 中间件概述

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

  • django默认自带的一些中间件:

    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',
    ] # MIDDLEWARE配置项是一个列表,列表中是一个个字符串,这些字符串其实是一个个类,也就是一个个中间件。
  • 自定义中间件

    # 中间件可以定义五个方法,分别是:
    
    process_request(self,request)
    process_view(self, request, view_func, view_args, view_kwargs)
    process_template_response(self,request,response)
    process_exception(self, request, exception)
    process_response(self, request, response) # 主要的是process_request和process_response
    # 以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。 # 注意:将自定义中间件添加到setting文件中MIDDLEWARE注意顺序
  • process_request

    def process_request(self, request):
    print("MD1里面的 process_request") # 1.process_request有一个参数,就是request,这个request和视图函数中的request是一样的
    # 2.process_request方法里面不写返回值,默认也是返回None,如果写了return None,也是一样的效果,不会中断请求,但是如果return 的一个httpresponse对象,那么就会在这个方法中断请求,直接返回给用户,这就成了非正常的流程了
    # 3.如果在这里return了httpresponse对象,那么会从这个中间件类中的process_response方法开始执行返回操作,所以这个类里面只要有process_response方法,肯定会执行

    示例代码:

    # settings.py的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',
    'middlewares.MD1', # 自定义中间件MD1,这个写的是项目路径下的一个路径,
    # 例如,如果放在项目下,文件夹名成为utils,那么这里应该写utils.middlewares.MD1
    'middlewares.MD2' # 自定义中间件MD2
    ]
    from django.utils.deprecation import MiddlewareMixin
    class MD1(MiddlewareMixin):
    def process_request(self, request):
    print("MD1里面的 process_request") class MD2(MiddlewareMixin):
    def process_request(self, request):
    print("MD2里面的 process_request")
    pass # 结果:
    MD1里面的 process_request
    MD2里面的 process_request
    app01 中的 index视图
  • process_response

    def process_response(self,request,response):
    return response # 1.它有两个参数,一个是request,一个是response,request就是上述例子中一样的对象,response是视图函数返回的HttpResponse对象。该方法的返回值也必须是HttpResponse对象
    # 2.注意:process_response函数要有return response返回值

    示例代码:

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse class Md1(MiddlewareMixin):
    def process_request(self,request):
    print("Md1请求") def process_response(self,request,response):
    print("Md1返回")
    return response class Md2(MiddlewareMixin):
    def process_request(self,request):
    print("Md2请求")
    # return HttpResponse("Md2中断")
    def process_response(self,request,response):
    print("Md2返回")
    return response **** # 结果:
    Md1请求
    Md2请求
    view函数...
    Md2返回
    Md1返回
  • process_view

    process_view(self, request, view_func, view_args, view_kwargs)
    
    # Django会在执行完url控制器后,调用视图函数之前调用process_view方法
    
    # 四个参数:
    # request是HttpRequest对象。
    # view_func是Django即将使用的视图函数/它是实际的函数对象,而不是函数的名称作为字符串。
    # view_args是将传递给视图的位置参数的列表.
    # view_kwargs是将传递给视图的关键字参数的字典/view_args和view_kwargs都不包含第一个视图参数(request)。 # 可以返回None或一个HttpResponse对象。
    # 如果返回None,Django将继续处理这个请求,执行任何其他中间件的process_view方法,然后在执行相应的视图。
    # 如果它返回一个HttpResponse对象,Django不会调用对应的视图函数。 它将执行中间件的process_response方法并将应用到该HttpResponse并返回结果。

    示例代码:

    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("-" * 80)
    print("MD1 中的process_view")
    print(view_func, view_func.__name__)
    # 就是url映射到的那个视图函数,也就是说每个中间件的这个process_view已经提前拿到了要执行的那个视图函数
    # ret = view_func(request) # 提前执行视图函数,不用到了上图的视图函数的位置再执行,如果视图函数有参数的话,可以这么写 view_func(request,view_args,view_kwargs)
    # return ret # 直接就在MD1中间件这里这个类的process_response给返回了,就不会去找到视图函数里面的这个函数去执行了。 class MD2(MiddlewareMixin):
    def process_request(self, request):
    print("MD2里面的 process_request")
    pass def process_response(self, request, response):
    print("MD2里面的 process_response")
    return response def process_view(self, request, view_func, view_args, view_kwargs):
    print("-" * 80)
    print("MD2 中的process_view")
    print(view_func, view_func.__name__) # 结果:
    MD2里面的 process_request
    MD1里面的 process_request
    -------------------------------------------------------------------------------
    MD2 中的process_view
    <function index at 0x000001DE68317488> index
    -------------------------------------------------------------------------------
    MD1 中的process_view
    <function index at 0x000001DE68317488> index
    app01 中的 index视图
    MD1里面的 process_response
    MD2里面的 process_response

    正常流程图:

    非正常流程图:

  • process_exception

    process_exception(self, request, exception)
    
    # 两个参数:
    # 1.一个HttpRequest对象
    # 2.一个exception是视图函数异常产生的Exception对象。 # 这个方法只有在视图函数中出现异常了才执行,它返回的值可以是一个None也可以是一个HttpResponse对象。
    # 如果是HttpResponse对象,Django将调用模板和中间件中的process_response方法,并返回给浏览器,否则将默认处理异常。
    # 如果返回一个None,则交给下一个中间件的process_exception方法来处理异常。它的执行顺序也是按照中间件注册顺序的倒序执行。

    代码示例:

    def index(request):
    print("app01 中的 index视图")
    raise ValueError("呵呵")
    return HttpResponse("O98K")
    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("-" * 80)
    print("MD1 中的process_view")
    print(view_func, view_func.__name__) def process_exception(self, request, exception):
    print(exception)
    print("MD1 中的process_exception") class MD2(MiddlewareMixin):
    def process_request(self, request):
    print("MD2里面的 process_request")
    pass def process_response(self, request, response):
    print("MD2里面的 process_response")
    return response def process_view(self, request, view_func, view_args, view_kwargs):
    print("-" * 80)
    print("MD2 中的process_view")
    print(view_func, view_func.__name__) def process_exception(self, request, exception):
    print(exception)
    print("MD2 中的process_exception") # 结果:
    MD1里面的 process_request
    MD2里面的 process_request
    --------------------------------------------------------------------------------
    MD1 中的process_view
    <function index at 0x0000022C09727488> index
    --------------------------------------------------------------------------------
    MD2 中的process_view
    <function index at 0x0000022C09727488> index
    app01 中的 index视图
    呵呵
    MD2 中的process_exception
    MD2里面的 process_response
    MD1里面的 process_response # 注意,这里并没有执行MD2的process_exception方法,因为MD1中的process_exception方法直接返回了一个响应对象。

    正常流程图:

    非正常流程图:

  • process_template_response

    process_template_response(self, request, response)
    
    # 参数:
    # 1.request是HttpRequest对象
    # 2.response是TemplateResponse对象(由视图函数或者中间件产生)。 # process_template_response是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)。

    代码示例:

    def index(request):
    print("app01 中的 index视图")
      #raise ValueError('出错啦')
    def render():
    print("in index/render")
    # raise ValueError('出错啦') # 至于render函数中报错了,那么会先执行process_template_response方法,然后执行process_exception方法,如果是在render方法外面报错了,那么就不会执行这个process_template_response方法了。
    return HttpResponse("O98K") # 返回的将是这个新的对象
    # raise ValueError('出错啦') 将报错放到这个位置不会报错
    rep = HttpResponse("OK")
    rep.render = render
    return rep
  • cookie认证/中间件版

    class M1(MiddlewareMixin):
    def process_request(self,request):
    # 设置路径白名单,只要访问的是login登陆路径,就不做这个cookie认证
    if request.path not in [reverse('login'),]:
    print('我是M1中间件')
    is_login = request.COOKIES.get('is_login', False)
    if is_login:
    pass
    else:
    # return render(request,'login.html')
    return redirect(reverse('login'))
    else:
    return None # 别忘了return None,或者直接写个pass def process_response(self,request,response):
    print('M1响应部分')
    return response

4. 中间件应用/登录认证

  • view

    from django.shortcuts import render,HttpResponse,redirect
    
    def login(request):
    if request.method == 'GET':
    return render(request,'login.html')
    else:
    name = request.POST.get('name')
    password = request.POST.get('password')
    if name == 'liu' and password == '123':
    request.session['is_login'] = True
    return redirect('index')
    else:
    return redirect('login') def index(request):
    return render(request,'index.html')
  • mymiddleware.py

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse,render,redirect class MD1(MiddlewareMixin):
    white_list = ['/login/']
    def process_request(self,request):
    print('请求来了')
    path = request.path
    if path not in self.white_list:
    status = request.session.get('is_login')
    if not status:
    return redirect('login') def process_response(self,request,response):
    print('响应走了')
    return response
  • login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <h1>登录页面</h1>
    <form action="" method="post">
    {% csrf_token %}
    用户名:<input type="text" name="name"> <!--input标签记得写name-->
    密码:<input type="text" name="password">
    <button class="submit">提交</button>
    </form>
    </body>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script></script>
    </html>

5. django请求生命周期

  • 流程描述:

    1. 在浏览器输入网址后,先经过DNS域名解析,解析出对应的ip
    2. 请求到达wsgi,在wsgi封装了socket,按着http协议解包,将请求封装成request对象
    3. 到达中间件,按顺序执行每个中间件的request方法
    4. 在url控制器中,映射到对应的视图函数
    5. 在视图函数中,进行数据库相关操作,以及模板渲染
    6. 将视图返回结果,返回到中间件,按倒序执行每个中间件的response方法
    7. 将返回结果通过wsgi,按照http协议封装响应数据,返回给浏览器
    8. 浏览器收到响应结果,对其进行渲染,展示页面

Django框架10 /sweetalert插件、django事务和锁、中间件、django请求生命周期的更多相关文章

  1. Django框架深入了解_01(Django请求生命周期、开发模式、cbv源码分析、restful规范、跨域、drf的安装及源码初识)

    一.Django请求生命周期: 前端发出请求到后端,通过Django处理.响应返回给前端相关结果的过程 先进入实现了wsgi协议的web服务器--->进入django中间件--->路由f分 ...

  2. 【转】Django框架请求生命周期

    https://www.cnblogs.com/gaoya666/p/9100626.html 先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行 ...

  3. Django框架请求生命周期

    先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校 ...

  4. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  5. [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]

    [Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...

  6. Django 框架 django的请求生命周期

    概述 首先我们知道HTTP请求及服务端响应中传输的所有数据都是字符串,同时http请求是无状态的,可以通过session和cookie来辅助. 浏览器通过ip和端口及路由方式访问服务端. 在Djang ...

  7. Django简介,请求生命周期,静态文件配置

    Web框架 ​ Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...

  8. Django请求生命周期和ORM

    dajngo请求生命周期 django请求生命周期是:当用户在browser点击URL后,在django后台都发生了什么. 请求响应Http 1.发送Http请求 2.服务器接收,根据请求头中url在 ...

  9. Django(35)Django请求生命周期分析(超详细)

    Django请求生命周期分析 1.客户端发送请求 在浏览器输入url地址,例如www.baidu.com,浏览器会自动补全协议(http),变为http://www.baidu.com,现在部分网站都 ...

随机推荐

  1. 小孩学习编程的绝佳游戏——CodeMonkey

    CodeMonkey于2014年1月在以色列成立.它的愿景是建立一个全球性的学习平台,让孩子们通过游戏的方式学习.发现.创造和分享,同时在此过程中获得编程这一项21世纪必备的技能. 通常提到CodeM ...

  2. MySQL示例数据库导入_1

    做个测试需要有适当量的数据库,于是找到了下面这个MySQL(超过30w记录), 1)先Git clone https://github.com/datacharmer/test_db         ...

  3. APP——python——自动化环境搭建01

    前提:python以及pycharm安装完成. ---------------------------------------------------------------------------- ...

  4. SpringBoot + Mybatis + Redis 整合入门项目

    这篇文章我决定一改以往的风格,以幽默风趣的故事博文来介绍如何整合 SpringBoot.Mybatis.Redis. 很久很久以前,森林里有一只可爱的小青蛙,他迈着沉重的步伐走向了找工作的道路,结果发 ...

  5. 使用SpringCloud Stream结合rabbitMQ实现消息消费失败重发机制

    前言:实际项目中经常遇到消息消费失败了,要进行消息的重发.比如支付消息消费失败后,要分不同时间段进行N次的消息重发提醒. 本文模拟场景 当金额少于100时,消息消费成功 当金额大于100,小于200时 ...

  6. npm: no such file or directory, scandir '.../node_modules/node-sass/vendor'

    运行vue报错 npm run dev 解决办法,运行:npm rebuild node-sass

  7. Error: Cannot find module 'webpack'

    运行 npm start 报错 Error: Cannot find module 'webpack' 安装了 npm install --save-dev webpack cnpm install ...

  8. 10TB级日志的秒级搜索

  9. RabbitMQ:三、进阶

    保证消息的安全 持久化 交换器持久化:声明交换器时指定持久化 队列持久化:声明队列时指定持久化 消息持久化:发送消息时指定持久化 一般队列和消息持久化要同时声明,此外消息假如进了交换器却找不到队列,也 ...

  10. bugku社工writeup

    最近bugku的web和杂项刷了多半,突然心血来潮想试试社工题,bugku的社工题比较基础,而且题量不多,和大家分享一下writeup. 1.密码 根据提示,多猜几次密码就对了,然后得到flag. 2 ...