首页 > 其他分享 >Django笔记十三之select_for_update等选择和更新等相关操作

Django笔记十三之select_for_update等选择和更新等相关操作

时间:2023-04-01 23:23:13浏览次数:64  
标签:Blog name tagline hunter update Django blog select

本篇笔记将介绍 update 和 create 的一些其他用法,目录如下:

  1. get_or_create
  2. update_or_create
  3. select_for_update
  4. bulk_create
  5. bulk_update

1、get_or_create

前面我们介绍过 get() 和 create() 的用法,那么 get_or_create() 的意思很简单,就是 获取或者创建,如果存在就返回,不存在就先创建再返回

假设对于 Blog model,我们想看下数据库有没有 name="hunter", tagline="tagline_test" 的数据,没有的话创建并获取这条数据,有的话,就直接获取。

在之前我们操作可能是:

try:
	blog = Blog.objects.get(name='hunter', tagline='tagline_test')
except Blog.DoesNotExist:
	blog = Blog(name='hunter', tagline='tagline_test')
	blog.save()		

现在我们可以直接这样操作:

blog, created = Blog.objects.get_or_create(name='hunter', tagline='tagline_test')

这个函数的返回值有两个,一个是操作的 model 实例,一个是是否是 created 的 布尔型数据。

created 为 True,表示这条数据是创建,create() 到的
created 为 False,表示这条数据是获取, get() 到的

注意: 查询的条件必须是唯一的,否则会造成多条数据返回而报错,这个逻辑同 get() 函数。

注意: 使用的字段,没有唯一的约束,并发的调用这个方法可能会导致多条相同的值插入。

字段默认值

假设 Blog 这个 model 除了 name, tagline 这两个字段外,还有 field_1 和 field_2 字段,但是他们不在我们查询的条件内,作用为在创建的时候设置的默认值,我们可以通过 defaults 来操作:

blog, created = Blog.objects.get_or_create(
	name='hunter', 
	tagline='tagline_test',
	defaults={
		'field_1': 'field_1_value',
		'field_2': 'field_2_value'
	}
)

最后关于这个函数,有个小提示,如果这个函数用在接口里,那么根据幂等性,我们应该使用 POST 方法来请求,而不是 GET 请求。

关于幂等性的概念,有兴趣的话可以去查询一下。

2、update_or_create

更新或者创建,使用方法同 get_or_create()

假设对于 Blog model 我们想实现的操作如果存在 name='hunter', tagline='tagline_test' 的数据就将其 field_1 和 field_2 的字段更新,不存在的话,就创建该数据。

之前的操作逻辑大概如下:

defaults = {"field_1": "field_1_value", "field_2": "field_2_value"}

try:
	obj = Blog.objects.get(name='hunter', tagline='tagline_test')
	for key, value in defaults.items():
		setattr(obj, key, value)
	obj.save()
except:
	new_values = {"name": "hunter", "tagline": "tagline_test}
	new_values.update(defaults)
	obj = Blog(**new_values)
	obj.save()

现在我们使用 update_or_create 可以如下操作:

obj, created = Blog.objects.update_or_create(
	name='hunter', tagline='tagline_test',
	defaults={"field_1": "field_1_value", "field_2": "field_2_value"}
)

3、select_for_update

select_for_update 的操作复杂一点,作用类似于 SQL 中的 SELECT ... FOR UPDATE 语句

操作如下:

from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
	for blog in blog_list:
		...

当 blog_list 去获取数据的时候,所有匹配上的 entries 都会被锁,直到这个事务结束。

意味着这个时候,其他的事务会被阻止更改或者重新在这些数据上加锁。

我们来举个例子,在我们执行下面的语句时:

import time
from django.db import transaction

blog_list = Blog.objects.select_for_update().filter(name="hunter")
with transaction.atomic():
	for blog in blog_list:
		print("locking ...")
		time.sleep(20)

这个时候,我们在重新开一个 shell,来执行下面的语句:

Blog.objects.filter(name="hunter").update(name="hunter_1")

因为第一个 shell 里执行的命令还没有结束,而且在数据上加了锁,因此第二个 shell 里的语句会进入等待,直到第一个 shell 里的命令执行完成之后,第二个 shell 里的命令才会执行。

注意: 如果在第一个命令里,对 blog 数据进行操作,比如 把 name 字段改为了 hunter_2,那么在第二条命令的条件里筛选不到结果然后更新的。

4、bulk_create

批量创建,在前面介绍增删改查的时候介绍过一次,这里再简单做一下示例:

from blog.models import Blog

blog_list = [
	Blog(name="hunter_1", tagline="tag_1"),
	Blog(name="hunter_2", tagline="tag_2"),
	Blog(name="hunter_3", tagline="tag_3"),
	Blog(name="hunter_4", tagline="tag_4")
]

Blog.objects.bulk_create(blog_list)

如果我们批量创建的数量过多,我们可以指定分批次来创建,通过 batch_size 参数来指定。

Blog.objects.bulk_create(blog_list, batch_size=2)

5、bulk_update

批量更新,方式与 bulk_create 的方式类似,以下是使用示例:

blog_list = Blog.objects.filter(id__lte=20)

for blog in blog_list:
	blog.name = "name_updated"
	blog.tagline = "tag_updated"

Blog.objects.bulk_update(blog_list, fields=['name'], batch_size=2)

需要注意的是 bulk_update 多了个参数,fields 这个是用来指定需要更新的字段。

如我们上面的命令所示,我们指定更新的是 name 字段,那么就算我们更改了 tagline 的数据,只要 fields 列表里没有指定该字段,那么后台也不会更新该字段。

以上就是本篇笔记全部内容,接下来我们将介绍一下查询中的其他用法,比如latest,first,contains 等。

本文首发于本人微信公众号:Hunter后端

原文链接:Django笔记十三之select_for_update等选择和更新等相关操作

如果想获取更多相关文章,可扫码关注阅读:
image

标签:Blog,name,tagline,hunter,update,Django,blog,select
From: https://www.cnblogs.com/hunterxiong/p/17279676.html

相关文章

  • selenium使用css selector和xpath的比较
    selenium提供的定位方式(常用)推荐的定位方式的优先级   优先级最高:ID   优先级其次:name   优先级再次:CSSselector   优先级再次:Xpath针对cssselector和xpath的优先级做一个简单的说明在项目中我们可能用的最多的是css或者xpath,那么针对这两种,我们优先选择css,原......
  • django 中model 的序列换
    方法一:from django.core import serializers ret = models.BookType.objects.all() data = serializers.serialize("json",ret) 方法二:当只有一个object时:fromdjango.forms.modelsimportmodel_to_dictdata=model_to_dict(yourmodelobject)......
  • 使用vSphere Update Manager 升级 ESXi 主机
    使用vSphereUpdateManager升级ESXi主机vSphereUpdateManager vSphereUpdateManager 是用于升级、迁移、更新和修补群集主机、虚拟机和客户机操作系统的软件。 vSphereUpdateManager 可协调主机和虚拟机的升级。如果站点使用 vSphereUpdateManager,VMware建议......
  • django:数据库的一些进阶知识点与应用
    一,连接池使用第三方程序向数据库发出数据操作请求前,都需要先创建到数据库的连接,这个操作会占用大量资源。所谓的资源消耗,一是对数据库连接数量的消耗;二是对系统内存资源的消耗;三是连接建立过程对时间的消耗,时间消耗角度可以参考这篇博客。django默认会在请求进来的时候创建......
  • Django: @login_required
    Django:Tweaking@login_requireddecorator我想为我的网站开始一个私人Beta版。我有一个初始页面,用户可以在其中输入代码,然后访问网站的其余部分。当前,所有其他站点页面(初始页面除外)都包含一系列通过要求用户登录(通过@login_required装饰器)设置的重定向。我希望登录......
  • Repository base is listed more than once in the configuration Repository updates
    下载软件包时报错:RepositorybaseislistedmorethanonceintheconfigurationRepositoryupdatesislistedmorethanonceintheconfigurationRepositoryextrasislistedmorethanonceintheconfigurationRepositorycentosplusislistedmorethanonceint......
  • ztree 更新节点updateNode无效
    https://blog.csdn.net/qq_42190134/article/details/126174038在使用updateNode时,如果node是自行声明的数据,那么更新时会不生效。因为自行声明的数据并没有在当前树中引用,更新时无法生效。constnode={id:15,name:'总部大楼',isParent:true,}varzTree=......
  • Python Django投稿系统代码
    PythonDjango投稿系统代码Python是一种高级编程语言,而Django则是一个基于Python的Web框架。使用Python和Django可以轻松地创建现代化、高效的Web应用程序,其中包括投稿系统。投稿系统是一个允许用户发布内容或文章的Web应用程序。Python和Django的结合使得创建投稿系统变得简单......
  • django自定义模板显示不同状态的颜色
    一般这个颜色列表是放在models.py里charge_type_class_mapping={1:"success",2:"danger",3:"default",4:"info",5:"primary",} color.pyfromdjango.templateimportLib......
  • scrapy爬虫框架(二)scrapy中Selector的使用
      在scrapy框架前,相信大家或多或少的已经了解了一些网页数据解析方法,如:xpath、bs4、正则表达式等,但是在scrapy框架中也有一个内置的数据提取方法--Selector。在这里我们就先简单介绍一下Selector在scrapy中的运用及常用方法。  为了方便示例,我们以官方文档中的示例页面源码进......