九、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文件中 -- 就没有模板渲染的步骤了 -- 就没有办法替换对应的模板语法.

原文地址:https://www.cnblogs.com/yangzm/p/11272687.html

时间: 2024-11-20 06:38:01

九、Django的锁、事务、ajax的相关文章

Django的锁和事务

Django的锁和事务 锁 select_for_update(nowait=False, skip_locked=False) 返回一个锁住行直到事务结束的查询集,如果数据库支持,它将生成一个 SELECT ... FOR UPDATE 语句. 举个例子: entries = Entry.objects.select_for_update().filter(author=request.user) 所有匹配的行将被锁定,直到事务结束.这意味着可以通过锁防止数据被其它事务修改. 一般情况下如果其

sql server中的锁 事务锁 更新锁 保持锁 共享锁 你知道吗?

锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 注意: 锁定数据库的一个表的区别 SELECT * FROM table WITH (HOLDLOCK) 其他事务可以读取表,但不能更新删除 SELECT * FROM table WITH (TABLOCKX) 其他事务不能读取表,更新和删除 SELECT 语句中"加锁选项"的功能说明 SQL Server提供了强大而完备的锁机制来帮助实现数据库系统的并发性和高性能.用户既能使用SQL Ser

sql锁 事务

1.数据库并发产生的问题.(这里所说的事务就是普通意义的流程,跟数据库的事务不要关联起来) 1)脏读.一个事读取了一个仍然在另一个未提交事务的范畴内的数据.read committed级别可以避免. 2)不可重复读.一个事务中两次相同的查询却返回了不同的数据.这是因为一个事务在读,然后另一个事务修改了数据,这个事务再去读,发现两次数据不一致. 3)幻读.没有锁定所有读取的行. 4)丢失更新. 2.各种锁(解决这些问题). 1)共享锁.用户在读取的时候其他用户可以读取,但是不能修改.select

django中如何实现ajax(post)日记选

上回的<Django和Ajax的那些事儿-Ajax Get>,讲过$.get(),它是从Django服务端获取我们想要的数据,然后渲染到前端html.今天说到Post方式,葫芦画瓢,让人想:会不会 有$.post().嗯,没错,的确有$.post(),官网示例:view plainprint? $.post("test.cgi",             { name: "John", time: "2pm" },          

django中数据库事务的处理

今天在django中处理数据库数据时,用到事务,官方文档看不下去,网上查资料,那叫一个大海捞针啊,还找不到自己想要的效果. django中的事务, 依据Django1.6的文档,“Django提供了一种简单的API去控制数据库的事务交易...原子操作用来定义数据库事务的属性. 原子操作允许我们在数据库保证的前提下,创建一堆代码.如果这些代码被成功的执行,所对应的改变也会提交到数据库中.如果有异常发生,那么操作就会回滚.”可以采用装饰器用法或代码块用法,强力推荐代码块,如下. from djang

Django表单form ajax应用(上)

一.项目说明 学习django版本1.8.2,把之前零散学习的知识整合下,主要涉及到: 项目开始,ajax数据调用,注册,数据录入,数据修改,数据删除,数据建模等完成一个完整的前后台功能简单的web.数据库默认用sqlite 1.创建djano项目:     $cd  /data1/DjangoProject/     $django-admin startproject School     $cd School     $python manage.py startapp student  

自动化运维Python系列之Django路由系统、Ajax请求

路由系统 路由系统负责分析处理用户请求网址内容,向后视图函数分发处理任务,根据对应的处理函数处理完成后给用户return模板渲染结果:路由系统分类很多,常见的有基本单一路由,正则路由,带额外参数路由,二层三层路由还有通过反射机制来完成的动态路由. 1)单一路由 url(r'^admin/', admin.site.urls) 2)基于正则的路由 url(r'^detail/(\d+)/', views.detail), url(r'^detail2/(?P<p1>\d+)/(?P<x2&

python 学习笔记十九 django项目bbs论坛

跨站请求伪造保护 CSRF 中间件和模板标签提供对跨站请求伪造简单易用的防护.某些恶意网站上包含链接.表单按钮或者JavaScript ,它们会利用登录过的用户在浏览器中的认证信息试图在你的网站上完成某些操作,这就是跨站攻击.还有另外一种相关的攻击叫做“登录CSRF”,攻击站点触发用户浏览器用其它人的认证信息登录到其它站点. 全局: 中间件 django.middleware.csrf.CsrfViewMiddleware 局部: @csrf_protect,为当前函数强制设置防跨站请求伪造功能

django中的事务管理

在讲解之前首先来了解一下数据库中的事务. 什么是数据库中的事务? 热心网友回答: (1):事务(Transaction)是并发控制的单位,是用户定义的一个操作序列.这些操作要么都做,要么都不做,是一个不可分割的工作单位.通过事务,SQL Server能将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性. (2):事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束. COMMIT表示提交,即提交事务的所有操作.具体地说就是将事务中所有对数据库的更新写回