当前位置: 首页 > 后端技术 > Python

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

时间:2023-03-26 17:40:37 Python

本篇笔记将介绍update和create的其他一些用法。get_or_create()的意思很简单,就是获取或者创建,存在则返回,不存在则先创建再返回。假设对于Blog模型,我们要查看数据库中是否有name="hunter"和tagline="tagline_test"的数据,如果没有,则创建并获取这些数据,如果有,则直接获取。以前我们的操作可能是:try:blog=Blog.objects.get(name='hunter',tagline='tagline_test')exceptBlog.DoesNotExist:blog=Blog(name='hunter',tagline='tagline_test')blog.save()现在我们可以直接这样操作:blog,created=Blog.objects.get_or_create(name='hunter',tagline='tagline_test')这个函数有两个返回值,一个是操作的模型实例,一个是创建的布尔数据。created为True,表示创建了这条数据,create()为False,表示获取了这条数据,通过get()注意:查询条件必须唯一,否则会出现多条数据被返回而不是报错,这个逻辑和get()函数是一样的。注意:使用的字段没有唯一性约束,并发调用该方法可能会导致多次插入同一个值。字段默认值假设Blog模型除了name和tagline这两个字段外还有field_1和field_2字段,但是它们不在我们查询的条件中,作为创建时设置的默认值.我们可以通过默认操作: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模型我们要实现操作如果有name='hunter',tagline='tagline_test'数据,则更新field_1和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')forkey,valueindefaults.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...FORUPDATE语句。该语句的操作如下:fromdjango.dbimporttransactionblog_list=Blog.objects.select_for_update().filter(name="hunter")withtransaction.atomic():forbloginblog_list:...当blog_list取数据时,所有匹配匹配的条目将被锁定直到事务结束意味着此时将阻止其他事务更改或重新锁定数据。举个例子,当我们执行下面的语句时:"locking...")time.sleep(20)这时候我们重新打开一个shell执行如下语句:Blog.objects.filter(name="hunter").update(name="hunter_1")因为第一个shell中执行的命令还没有执行完,数据被锁定,第二个shell中的语句会等到第一个shell中的命令执行完毕,第二个shell中的命令才会执行.注意:如果在第一条命令中对博客数据进行操作,比如将name字段改成hunter_2,则不能在第二条命令的条件下过滤结果再更新。4.bulk_create批量创建。增删改查时引入一次。这是一个简单的例子:fromblog.modelsimportBlogblog_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)forbloginblog_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的数据,只要字段列表中没有指定该字段,后台就不会更新该字段。以上就是这篇笔记的全部内容,接下来我们会介绍查询中的其他用法,比如latest、first、contains等。