zoukankan      html  css  js  c++  java
  • 九、Django的锁、事务、ajax

    一、事务和锁

    1. 行级锁

    select_for_update 注意必须用在事务里面

    select_for_update(nowait=False, skip_locked=False)

    entries = Entry.objects.select_for_update().filter(author=request.user)  #加互斥锁,由于mysql在查询时自动加的是共享锁,所以我们可以手动加上互斥锁。create、update、delete操作时,mysql自动加行级互斥锁
    
    select * from t1 where id=1 for update;
    models.T1.objects.select_for_update().fitler(id=1)
    

    所有匹配的行将被锁定,直到事务结束。这意味着可以通过锁防止数据被其它事务修改。

    1. 事务

    第一种方式:全局的

    这种方式是统一个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败),是全局性的配置

    在settings文件中:
    
    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', 
                ......
      } #还可以配置其他数据库
    }
    

    第二种方式:局部的

    通过transaction中的atomic代码块实现

    from django.db import transaction  # 导入transaction
    
    在视图函数中加:
    @transaction.non_atomic_requests
    def index(request):
        pass (orm...sql..语句)
    	return xxx
    
    上下文逻辑里面加:
    def index(request):
        ..
        with transaction.atomic():  # 设置事务的保存点
            pass orm...sql..
        ...
        return xxx
    

    二、Ajax

    1. 简介

      AJAX (Asynchronous Javascript And XML) ,翻译成中文是“异步的Javascript和XML” ,即使用Javascript语言与服务器进行异步交互,传输的数据为XML 。

      AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

      AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行

    AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;

    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求
    • 局部刷新:这一特点给用户的感受是在不知不觉中完成请求和响应过程
    1. 普通的登录认证示例

    首先不用ajax,完成一个登录认证的界面

    1. 配置路由 urls
      from app01 import views
      urlpatterns = [
      url(r'^login/', views.LoginView.as_view(),name='login'),
      # 这是CBV开始时配置的路径
      ]

    2. CBV的方式完成视图函数
      from django.shortcuts import render,HttpResponse,redirect
      from django.views import View

      class LoginView(View):
          def get(self,request):
              return render(request,'login.html')
      
          def post(self,request):
              name = request.POST.get('username')
              pwd = request.POST.get('password')
              if name=='yangzm' and pwd=='123':
                  return render(request,'index.html')
              else:
                  return redirect('login')
      
    3. 完成两个html文件,login.html用来完成登录功能;index.html文件完成登录成功后显示的页面,如果用户名密码错误,重定向会login.html的页面
      # login.html

      欢迎来到登录页面



      {% csrf_token %}
      用户名:
      密 码:

      # index.html
      <p>登录成功</p>
      <p>欢迎大佬到来</p>
      
    4. 结果和分析缺点
      用户输入127.0.0.1:8000/login/时,显示登录页面
      登录成功跳转index页面,登录失败重新返回这个页面

      分析缺点:当用户输入信息不正确的时候,因为做了重定向,点击提交后,页面刷新,跳转回了login页面,此时是又重新请求的页面,所以以前输入的数据将会被清空,这样对用户来说,体验是极差的
      改进的目标:用户输入错误时,要保留之前的信息,并提示用户输入错了,然后让用户在输入的内容上改,提高用户的体验,这时,就需要用到ajax来完成这个功能

    5. 基于ajax完成的登录认证示例

    6. ajax需要用到jquery的文件,所以先配置静态文件引入
      # 配置settings:
      STATICFILES_DIRS=[
      os.path.join(BASE_DIR,'statics')
      ]

      # 新建文件夹statics,放静态文件 jquery.js
      
    7. 此时login.html文件需要引入jquery文件,然后写js代码,实现ajax
      {% load static %}

      <body>
      <h1>欢迎来到登录页面</h1>
      
      <form action="/login/" method="post">
          {% csrf_token %}
          用户名:<input type="text" id="username" name="username">
          密  码:<input type="password" id="password" name="password">
          <input type="button" id="btn" value="提交">
          <span style="color: red;font-size: 12px" id="error"></span>
      </form>
      
      
      <script src="{% static 'jquery.js' %}"></script>
      <script>
          $('#btn').click(function () {
              $.ajax({
                  url:'/login/',
                  type:'post',
                  data:{
                      uname:$('#username').val(),
                      pwd:$('#password').val(),
                      csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val()
                      # 这是为了通过post提交的认证机制
      
                  },
                  success:function (res) {
                      var resStr = JSON.parse(res);
                      if(resStr['code'] === 3){
                          $('#error').text(resStr['redirect_url'])
                      }
                      else if(resStr['code'] === 0){
                          location.href=resStr['redirect_url'];
                      }
                  }
              })
          })
      </script>
      
      </body>
      
    8. url需要重新配置一个登录成功的index路径
      urlpatterns = [
      url(r'^admin/', admin.site.urls),
      url(r'^login/', views.LoginView.as_view(),name='login'),
      url(r'^index/', views.index),
      ]

    9. 视图函数views
      from django.shortcuts import render,HttpResponse,redirect

      # Create your views here.
      
      from django.views import View
      
      class LoginView(View):
          def get(self,request):
              return render(request,'login.html')
      
          def post(self,request):
              name = request.POST.get('uname')
              pwd = request.POST.get('pwd')
              if name=='yangzm' and pwd=='123':
                  ret = '{"code":0,"redirect_url":"/index/"}'
                  return HttpResponse(ret)
              else:
                  ret = '{"code":3,"redirect_url":"用户名密码错误!!!"}'
                  return HttpResponse(ret)
      
      def index(request):
      
          return render(request,'index.html')
      
    10. 结果

      此时输入了错误的用户名密码,不会刷新页面,显示提示的信息,保留原来的数据,直到输入对了跳转到登录成功的页面

    11. 外部文件导入的方式来写js代码,那么js代码中不能写django的模板语法,因为html文件的加载顺序:url--视图--html模板渲染 --- return给浏览器 -- 浏览器渲染 --- srcipt的src --才去请求js文件 --那么这个js文件的代码此时才加载到你的html文件中 -- 就没有模板渲染的步骤了 -- 就没有办法替换对应的模板语法.

  • 相关阅读:
    Spring 学习十五 AOP
    Spring 学习十四 Spring security安全
    博客文格式优化
    作为一名软件测试工程师,需要具备哪些能力
    单元测试工程师需要具备的任职资格
    初识安全测试(一)
    压力测试工具JMeter入门教程
    Jmeter的优点是什么?除了轻量级,它和LoadRunner有什么本质区别
    初识Jmeter(一)
    初识Selenium(四)
  • 原文地址:https://www.cnblogs.com/yangzm/p/11272687.html
Copyright © 2011-2022 走看看