一、ORM中的事务和锁

事务

事务要确保原子性

"""
事务ACID原子性:不可分隔的最小单位一致性:跟原子性是相辅相成隔离性:事务之间相互不干扰持久性:事务一旦确认永久生效事务的回滚rollback事务的确认commit
"""
# 目前是需要
from django.db import transactionwith transaction.atomic(): 开启事务# sql1# sql2# 的with代码块中写的所有orm操作都是属于同一个事务
print("执行其他操作")import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")import djangodjango.setup()from app01 import modelsfrom django.db import transaction
from django.db.models import F, Q# 事务要确保原子性
# 原子性:一个原子事务要么完整执行,要么干脆不执行。这意味着,工作单元中的每项任务都必须正确执行。如果有任一任务执行失败,则整个工作单元或事务就会被终止。
try:with transaction.atomic(): # 开启事务# 一系列的操作models.Book.objects.all().update(kucun=F("kucun") - 10)models.Book.objects.all().update(sale=F("sale") + 10)
except Exception as e:print(e)

下面再说一些设置事务的小原则吧:

1.保持事务短小

2.尽量避免事务中rollback

3.尽量避免savepoint

4.默认情况下,依赖于悲观锁

5.为吞吐量要求苛刻的事务考虑乐观锁

6.显示声明打开事务

7.锁的行越少越好,锁的时间越短越好

行级锁

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

表锁

class LockingManager(models.Manager):""" Add lock/unlock functionality to manager.
Example::class Job(models.Model): #其实不用这么负载,直接在orm创建表的时候,给这个表定义一个lock和unlock方法,借助django提供的connection模块来发送锁表的原生sql语句和解锁的原生sql语句就可以了,不用外层的这个LckingManager(model.Manager)类manager = LockingManager()counter = models.IntegerField(null=True, default=0)@staticmethoddef do_atomic_update(job_id)''' Updates job integer, keeping it below 5 '''try:# Ensure only one HTTP request can do this update at once.Job.objects.lock()job = Job.object.get(id=job_id)# If we don't lock the tables two simultanous# requests might both increase the counter# going over 5if job.counter < 5:job.counter += 1                                        job.save()finally:Job.objects.unlock()
"""    def lock(self):""" Lock table. Locks the object model table so that atomic update is possible.Simulatenous database access request pend until the lock is unlock()'ed.Note: If you need to lock multiple tables, you need to do lock themall in one SQL clause and this function is not enough. To avoiddead lock, all tables must be locked in the same order.See http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html"""cursor = connection.cursor()table = self.model._meta.db_tablelogger.debug("Locking table %s" % table)cursor.execute("LOCK TABLES %s WRITE" % table)row = cursor.fetchone()return rowdef unlock(self):""" Unlock the table. """cursor = connection.cursor()table = self.model._meta.db_tablecursor.execute("UNLOCK TABLES")row = cursor.fetchone()return row

二、Ajax

参考www.cnblogs.com/clschao/art…

1.简介

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

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

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

a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程

特性:1.异步请求2.局部刷新<script>$('#btn').click(function () {$.ajax({{#url:'/login/',#}url:"{% url 'login' %}",type:'post',data:{csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),{#csrfmiddlewaretoken:"{{ csrf_token }}",#}name:$('#username').val(),pwd:$('#password').val(),},success:function (res) {var resStr = JSON.parse(res)if (resStr['code'] == 0){location.href=resStr['redirect_url']}else{if(resStr['code'] == 3){var spanEle = document.createElement('span');$(spanEle).text(resStr['warning'])$('form').append(spanEle)}}console.log(resStr)}})})

2.ajax请求和响应

# urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^login/', views.LoginView.as_view(),name='login'),url(r'^index/', views.IndexView.as_view()),
]
# views.py
class LoginView(View):def get(self, request):# return render(request, reverse('login'))return render(request, 'login.html')def post(self, request):# name = request.POST.get('username')# password = request.POST.get('passwoame')name = request.POST.get('name')password = request.POST.get('pwd')print(name, password)if name == 'laowang' and password == '123':ret = {'code': 0, 'redirect_url': '/index/'}ret = json.dumps(ret)return HttpResponse(ret)else:ret = {'code':3,'warning': '用户名或者密码错误!!!'}ret = json.dumps(ret)# return HttpResponse(ret)return HttpResponse(ret, content_type='application/json') # 加上这个后在ajax中就不必在进行json解析了class IndexView(View):def get(self,request):return render(request, 'index.html')
# login.html
<body>
<h1>你好,世界!</h1>
<form action="/login/" method="post">{% csrf_token %}用户名: <input type="text" id="username" name="username">密码:   <input type="password" id="password" name="password">
{#    submit和button就会触发form表单请求#}
{#    <input type="submit" id="btn">#}
{#    <button></button>#}<input type="button" id="btn" value="提交">
</form>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>$('#btn').click(function () {$.ajax({{#url:'/login/',#}url:"{% url 'login' %}",type:'post',data:{csrfmiddlewaretoken:$('[name=csrfmiddlewaretoken]').val(),{#csrfmiddlewaretoken:"{{ csrf_token }}",#}name:$('#username').val(),pwd:$('#password').val(),},success:function (res) {// var resStr = JSON.parse(res)if (resStr['code'] == 0){location.href=resStr['redirect_url']}else{if(resStr['code'] == 3){var spanEle = document.createElement('span');$(spanEle).text(resStr['warning'])$('form').append(spanEle)}}console.log(resStr)}})})
</script>
</script>
</body>from django.http import JsonResponse
# 这种回复最方便,直接Json了,也不用导入Json
if name == 'laowang' and password == '123':ret = {'code': 0, 'redirect_url': '/index/'}# ret = json.dumps(ret)return JsonResponse(ret)# return HttpResponse(ret, ontent_type='application/json') # 加上这个后在ajax中就不必在进行json解析了

三、form表单上传文件

{#enctype="multipart/form-data"  必须指定contenttype#}
<form action="/upload/" method="post" enctype="multipart/form-data">{% csrf_token %}头像:<input type="file" name="headicon">用户名:<input type="text" name="name">密码:<input type="password" name="pwd"><input type="submit">
</form># views.py
class UploadView(View):    def get(self, request):        return render(request, 'upload.html')    def post(self, request):        print(request.FILES)  # <MultiValueDict: {'headicon': [<InMemoryUploadedFile: 佩奇.png (image/png)>]}>        file_obj = request.FILES.get('headicon') # 文件数据需要用request.FILES去拿        print(file_obj)        file_name = file_obj.name        path = os.path.join(settings.BASE_DIR, 'static', 'img', file_name)        # with open('static/img/'+file_name, 'wb') as f:        with open(path, 'wb') as f:           # for i in file_obj:              #   f.write(i)            for chunck in file_obj.chuncks() # 一次返回65536B,可以设置chunck_size的大小            f.write(chunck)        return HttpResponse('ok')

文件的上传 二

views.py
from django.shortcuts
import render, HttpResponsefrom django.views
import View# 用CBV的模式class Upload(View):
def get(self, request):        return render(request, "Upload.html")
def post(self, request):        # 获取文件之前一定要改form表单里面的enctype="multipart/form-data"        print(request.FILES)  # <MultiValueDict: {'file_name': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}>        # 获取用户上传的文件        file_path = request.FILES.get("file_name")        print(file_path, type(file_path))  # 获取得就是文件名1.jpg<class 'django.core.files.uploadedfile.InMemoryUploadedFile'>       print(file_path.name, type(file_path.name))  # 1.jpg <class 'str'>        with open(file_path.name, "wb")as f:  # 因为file_path获得的是一个文件对象,所以要.name一下            for i in file_path:                f.write(i)        return HttpResponse("ok")Upload.html
{# 一定要修改enctype="multipart/form-data,还有不要忘记csrf_token #}
<form action="" method="post" enctype="multipart/form-data">    {% csrf_token %}
<input type="file" name="file_name" >
<button>上传</button></form>urls.pyurlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^upload/', views.Upload.as_view()),  #不要忘记括号
]

file_path.name:上传文件的名字

form表单注意的点:

  1. form标签的属性action 指定提交的地址(不写默认当前地址),method请求方法(默认为get)

  2. input标签要有name属性,有的标签还需要有value

  3. 有一个button按钮或者是type="submit"的input标签(只能用submit提交)

    #这里如果是method="get"的话,就会改变原url

    请输入你的电子邮箱

    Email address Password

    记住我的选择

    Sign in

novalidate:不进行格式验证

这里如果是method="get"的话,就会改变原url http://127.0.0.1:8000/login/?user=abc&pwd=123 :会让安全不严谨

目前要提交POST请求的必要操作:

在setings.py中注释一个中间键

MIDDLEWARE = [ #中间键    'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',  注释掉了可以提交POST请求
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

在urls.py中对数据进行操作(登录成功就返回一个页面,登录失败就返回原来页面)

def login(requests):    print(requests, type(requests))  # 这里的requests,是一个类    print(requests.method, type(requests.method))  # 获得它的方法,POST GET    print(requests.POST, type(requests.POST.get("user")))  # 在POST请求前关掉一个中间键   #  处理POST请求的逻辑    if requests.method == "POST":        #  获取用户提交的用户和密码        user = requests.POST.get("user")        pwd = requests.POST.get("pwd")        #  先设置一个固定的值 (以后会导入数据库)        if user == "abc" and pwd == "123":            # 校验成功,返回            return render(requests, "login2.html")    # 校验失败    return render(requests, "login.html")

四、ajax

ajax文件上传

Ajax头像:<input type="file" id="file">
Ajax用户名<input type="text" id="uname">
<button id="btn">提交</button>
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依赖 jQuery,所以必须放在前边) -->
<script src="{% static 'js/jquery.js' %}"></script>
<script>
$('#btn').click(function () {        var formdata = new FormData();  // 可以携带文件数据        formdata.append('name', $('#uname').val());        formdata.append('file_obj', $('#file')[0].files[0]);        formdata.append('csrfmiddlewaretoken', $('[name=csrfmiddlewaretoken]').val());        $.ajax({            url:'/upload',            type:'post',            {#data:{#}            {#    name:$('#uname').val(),#}            {#    file_obj:$('#file')[0].files[0],#}            data:formdata,            processData:false, // 不处理数据            contentType:false, // 不设置内容类型            success:function (res){                console.log(res)            }
})
})</script>class UploadView(View):    def get(self, request):        return render(request, 'upload.html')    def post(self, request):        print(request.FILES) # <MultiValueDict: {'headicon': [<InMemoryUploadedFile: 佩奇.png (image/png)>]}>        # file_obj = request.FILES.get('headicon') # 文件数据需要用request.FILES去拿        file_obj = request.FILES.get('file_obj')  # 文件数据需要用request.FILES去拿        print(file_obj)        file_name = file_obj.name        path = os.path.join(settings.BASE_DIR, 'static', 'img', file_name)        # with open('static/img/'+file_name, 'wb') as f:        with open(path, 'wb') as f:            # for i in file_obj:            #     f.write(i)            for chunk in file_obj.chunks():  # 一次饭hi65536B                f.write(chunk)        return HttpResponse('ok')

用ajax完成加法操作

  1. urls.py

    urlpatterns = [
    url(r’^admin/’, admin.site.urls),
    url(r’^index/’, views.index),
    url(r’^calc/’, views.calc),
    ]

  2. views.py

    def index(request):
    return render(request, “index.html”, locals())
    def calc(request):
    x1 = request.GET.get(“x1”)
    x2 = request.GET.get(“x2”)
    print(x1)
    print(x2)
    time.sleep(3) # 暂停3秒测试异步
    l3 = int(x1) + int(x2)
    return HttpResponse(l3) # 在response里面给我返回了计算的结果

  3. index.html

    + = 计算

ajax的接收参数的操作

views.py

import json
from django.http.response
import JsonResponse
def text(request):    print(request.GET)    xqu = json.loads(request.GET.get("xqu")) #接收ajax参数,把接收的字符串传化为json   print(xqu, type(xqu))    return JsonResponse({"status":200,"msg":"ok"})  #给ajax返回信息

html

 $("#b3").click(function () {       $.ajax({            url:"/text/",            type:"get",            data:{ #ajax给函数传递信息                name: 'aaa',                age: 15,                xqu: JSON.stringify(['抽烟','喝酒','烫头']), # 可以直接传递字符串            },  success:function (data) { #接收函数返回的信息                console.log(data)                console.log(data.msg)                console.log(data.status)           },        });    });

用ajax实现删除

用地址跳转删除的(跳转是要刷新页面的)

html代码

{#实现ajax实现删除功能#}
<button url="{% url 'del' 'publisher' i.pk %}" class="btn btn-danger btn-sm" >删除</button>$(".btn-danger").click(function () {        $.ajax({            url:$(this).attr('url'),            type:"get",            success:function (data) {  //接收不能重定向,所以接收的是地址                //用地址跳转                location.href  = data           }        })
})

views.py

@is_cookies
def delete(request, name, pk):  # 代码    return  HttpResponse(reverse(name))  #返回的字符串

不用跳转的删除

html代码

{#实现ajax实现删除功能#}
<button url="{% url 'del' 'publisher' i.pk %}" class="btn btn-danger btn-sm" >删除</button>
ajax
<script>    $(".btn-danger").click(function () {        $.ajax({            url:$(this).attr('url'),            type:"get",           success:function (data) {  //接收不能重定向,所以接收的是地址                //用地址跳转                {#location.href  = data#}                if(data.status===200){                    //后端删除成功,前面删除该行                    _this.parent().parent().remove()                }            }        })
})

views.py

@is_cookies
def delete(request, name, pk):  # 代码    return JsonResponse({"status":200})  #返回一个字典,让ajax提取如果是200的话,就删除本页面的th标签

sweetalert的使用(弹窗效果)

给ajax删除,添加的sweetalert弹窗效果

  1. 导入script

更多样式弹窗样式的网站:sweetalert.js.org/guides/

AJAX资料网:www.cnblogs.com/maple-shaw/…

五、JSON

轻量级的文本数据交换格式

python

支持的数据类型

字符串  数据  布尔  列表  字典  None

序列化

python的数据类型 --> json字符串

反序列话

json字符串 --> python的数据类型

给视图函数添加csrf校验

方法一:

from  django.views.decorators.csrf
import  csrf_exempt,csrf_protect@csrf_exempt  加在视图上  该视图不需要进行csrf校验@csrf_protect 加在视图上  该视图需要进行csrf校验@ensure_csrf_cookie 加在视图上 确保返回时设置csrftoken的cookie

csrf的校验原理

从cookie中获取csrftoken的值从request.POST中获取csrfmiddlewaretoken的值或者从请求头中获取x-csrftoken的值把这两个值对比,对比成功就接受请求,反之拒绝

让ajax可以通过django的csrf的校验:

给html的ajax添加csrf校验

方法二:

  1. 直接给ajax中的data添加csrfmiddlewaretoken的键值对

    data:{
    csrfmiddlewaretoken:$(’[name="csrfmiddlewaretoken]’).val(),
    name: ‘aaa’,
    age: 15,
    xqu: JSON.stringify([‘抽烟’,‘喝酒’,‘烫头’]),
    },

前提:必须有csrftoken的cookie的

  • 使用{% csrf_token%}

  • 使用ensure_csrf_cookie的装饰器,加在视图上
    from django.views.decorators.csrf import ensure_csrf_cookie

    1. 给header添加x-csrftoken的键值对(导入文件的方式)

    1.把header添加到ajax中
    $.ajax({
    url:"/calc2/",
    type:“post”,
    headers: {“X-CSRFToken”: KaTeX parse error: Expected 'EOF', got '}' at position 38: …etoken]').val()}̲, // 从Cookie取c…(’[name=“l11”]’).val(),
    “x2”:KaTeX parse error: Expected 'EOF', got '}' at position 43: … }̲, …/.test(method));}

最终推荐:导入文件+确保有cookie(最后面这种)

import json
from datetime import datetime
from datetime import date#对含有日期格式数据的json数据进行转换
class JsonCustomEncoder(json.JSONEncoder):    def default(self, field):        if isinstance(field,datetime):            return field.strftime('%Y-%m-%d %H:%M:%S')        elif isinstance(field,date):            return field.strftime('%Y-%m-%d')        else:            return json.JSONEncoder.default(self,field)d1 = datetime.now()dd = json.dumps(d1,cls=JsonCustomEncoder)print(dd)

ORM中的事务和锁、Ajax异步请求和局部刷新、Ajax文件上传、日期时间类型的Json、多表查询图书系统相关推荐

  1. ajax请求携带tooken_Spring Boot+Vue 文件上传,如何携带令牌信息?

    关于文件上传这块,松哥之前也写了好几篇文章了,甚至还有视频: Spring Boot+Vue+FastDFS 实现前后端分离文件上传 但是,之前和小伙伴们提到的方案,是基于 session 来做认证的 ...

  2. jQuery框架+DWR框架实现的Java Web中的Ajax效果(异步请求,局部刷新)

    一 简介和实现效果 这里用一个小例子来简单举例说明,做一个搜索引擎搜索提示效果,通过不断输入字符,然后在下方给出搜索提示.效果图如下: 通过上图可以看到,当输入一个"a"时,提示了 ...

  3. PHP_APC+Ajax实现的监视进度条的文件上传

    //load.js: ADS.addEvent(window, 'load', function(event) {var fileList = ADS.$('fileList');//按照需要修改uo ...

  4. ajax利用FormData、FileReader实现多文件上传php获取

    一.FormData方式 前台代码(注意,不需要用到form标签): a. html部分: b. js部分: c. 完整代码: <!DOCTYPE html> <html lang= ...

  5. php处理form多文件上传,ajax利用FormData、FileReader实现多文件上传php获取

    前台代码(注意,不需要用到form标签): a. html部分: b. js部分: c. 完整代码: function loadDoc(file,data,async=true){ if(window ...

  6. html弹窗赋值给查询框,bootstrap模态框动态赋值, ajax异步请求数据后给id为queryInfo的模态框赋值并弹出模态框(JS)...

    /查询单个 function query(id) { $.ajax({ url : "/small/productServlet", async : true, type : &q ...

  7. AJAX 异步请求详细教程

    文章目录 AJAX 异步请求 简介 Jquery 版 Ajax $.ajax() -- Jquery提供的 ajax 函数 注册验证用户名是否可用 $.get() 与 $.post() Ajax 返回 ...

  8. Ajax异步请求原理

    一.Ajax能做什么 异步请求.局部刷新 二.同步请求 JavaScript的特点是单线程,也正是因为单线程造成了同步请求 1. 为什么JS是单线程: JS 作为游览器脚本语言,主要用途是和用户交互. ...

  9. ajax异步文件上传和进度条

    一.ajax异步文件上传 之前有说过在form表单内的文件上传,但是会刷新页面,下面就来实现不刷新页面的异步文件上传 <div class="uploding_div"> ...

最新文章

  1. pip install Read timed out 超时问题解决
  2. 不可不知 DDoS的攻击原理与防御方法(2)
  3. Leetcode 141.环形链表
  4. Swift之源码编译的环境搭建和编译流程
  5. [HIVE] shell调用hive客户端导致nohup后台进程stopped
  6. poj 2503 Trie树
  7. 定时任务的并发_03
  8. 赋予用户最高权限的一点“挫折”
  9. 荣耀手表gspro会用鸿蒙,真实使用荣耀手表GS Pro功能用2个月评测反馈!一定看看如何!...
  10. 如何访问.then()链中的先前的诺言结果?
  11. Linux主机无法安装软件故障排查
  12. 数字电子技术基础第三版杨志忠_阎石《数字电子技术基础》(第6版)笔记和课后习题(含考研真题)详解复习笔记资料...
  13. Instsrv.exe和Srvany.exe的使用方法
  14. 小米pro笔记本2017款BIOS降级0603
  15. 域名证书是什么样子的_什么是网站域名证书
  16. 8K摄像机研发之路有多难?一起了解你不知道的首款国产8K小型化广播级摄像机背后的故事
  17. 别错过这张AI商用清单:你的生产难题可能被一个应用解决!
  18. 做了9年程序员,为什么我还摆脱不了复制粘贴?
  19. Ubuntu18.04安装Google浏览器
  20. fm24c16c语言程序,铁电存储器FM24C16的页面写和任意字节读汇编程序

热门文章

  1. MVP 模式实例解析(转)
  2. 条件运算符和条件表达式
  3. 诗与远方:无题(二十二)
  4. 诗与远方:无题(十八)
  5. vue部分样式无法修改
  6. 【转载】JSON介绍
  7. Eclipse使用技巧
  8. 【SpringCloud从0到6】 第一节:初识微服务微服务的雪崩效应
  9. linux系统下安装和配置redis(2021版)
  10. vue——vuex mapState,mapGetters,mapMutations,mapActions