Django数据库操作之save与update的使用
Python框架Django有着诸多优点,它提供的models可以让开发者方便地操作数据库,但正是由于对上层的良好的封装,使得提升数据库操作性能必须要清楚地知道Django的数据库操作到底执行了哪些SQL语句。
例如数据更新操作,对单条记录,可以使用save或者是update两种方式
在Django工程下的settings.py下将log设置为DEBUG,即可查看save和update分别执行了哪些SQL语句
如有一张表名叫做Example
使用save:
k=Example.objects.get(id=481) k.total_calories=12 k.save()
执行的SQL语句如下所示:
SELECT(1)AS`a`FROM`Example`WHERE`
Example`.`id`=481LIMIT1;args=(481,)
UPDATE`Example`SET`user_id`=asdfasdf,`event_id`=-1,`join_type`=0,`name`=,`phon
e`=,`email`=,`company_name`=,`address`=,`if_type`=0,`code`=,`l
ocation`=,`total_days`=0,`total_length`=0,`total_calories`=12,`comme
nts`=,`reserved_1`=,`reserved_2`=,`reserved_3`=,`reserved_4`=,`re
served_5`=,`create_datetime`=2015-02-0217:43:53WHERE`Example`
.`id`=481;args=(u'asdfasdf',-1,0,u'',u'',u'
',u'',u'',0,u'',u'',0,0,12,u'',u'',u'',u'',u'',u'',u'2015-02-021
7:43:53',481)
首先要查询k这条记录,然后save()的时候提交更新的内容,发现更新的时候把Example中的有字段都SET赋值的一次
使用update
Example.objects.filter(id=481).update(total_calories=10)
执行的SQL语句是:
UPDATE`Example`SET`total_calories`=1 0WHERE(`Example`.`user_id`=asdfasdf AND`Example`.`id`=481);args=(10,u'asdfasdf',481)
这条SQL语句简短而且执行速度要优于使用save的速度。
从SQL的执行情况来看,使用upate是要优于save方式的。
从使用情境上看,update更加适用于批量数据更新,而save则更适合当然也只适合做单条记录的数据更新操作了。
在使用Django的数据模型操作数据库时,了解这些底层的SQL操作很有必要。
补充知识:如何理解Django的save(commit=False)方法和save_m2m()方法
什么时候使用save(commit=False)方法,save_m2m方法以及如何使用是Django表单forms进阶必需了解的知识。我们今天就带你来看一看。
何时使用save(commit=False)方法
Stackoverflow上其实已经有了一段非常精炼的答案。英文原文如下,我把它翻译了一下:
That'susefulwhenyougetmostofyourmodeldatafromaform,butneedtopopulatesomenull=Falsefieldswithnon-formdata.Savingwithcommit=Falsegetsyouamodelobject,thenyoucanaddyourextradataandsaveit.
当你通过表单获取你的模型数据,但是需要给模型里null=False字段添加一些非表单的数据,该方法会非常有用。如果你指定commit=False,那么save方法不会理解将表单数据存储到数据库,而是给你返回一个当前对象。这时你可以添加表单以外的额外数据,再一起存储。
save(commit=False)方法实际应用案例
下面我们来看一个实际应用案例。我们创建了一个叫文章Article的模型,里面包含title,body和作者author等多个字段,其中author字段非空null=False。我们由Article模型创建了一个ArticleForm表单,可以让用户发表新文章,但是我们故意把author字段除外了,因为我们不希望用户编辑作者。
最后用户提交的表单数据里肯定没有author,当这样的数据提交到数据库时肯定会有问题的。所以我们先通过article=form.save(commit=False)创建article实例,此时让Django先不要发送数据到数据库,等待我们把author添加好后,再把数据一起存储到数据库中。
下面是视图文件views.py的代码。最重要的是ArticleForm构成和article_create方法。
from.modelsimportArticle fromdjango.formsimportModelForm fromdjango.httpimportHttpResponseRedirect fromdjango.shortcutsimportrender classArticleForm(ModelForm): classMeta: model=Article exclude=['author'] defarticle_create(request): ifrequest.method=='POST': form=ArticleForm(request.POST) ifform.is_valid(): article=form.save(commit=False) #commit=False告诉Django先不提交到数据库. article.author=request.user#添加额外数据 article.save()#发送到数据库 returnHttpResponseRedirect("/blog/") else: form=ArticleForm() returnrender(request,'blog/article_create_form.html',{'form':form})
如果你使用Django自带的基于类的视图(CBV),你可以使用form_valid方法完成上述同样的操作。具体代码如下。
fromdjango.views.generic.editimportCreateView from.modelsimportArticle fromdjango.formsimportModelForm #Createyourviewshere. classArticleForm(ModelForm): classMeta: model=Article exclude=['author'] classArticleCreateView(CreateView): model=Article form_class=ArticleForm template_name='blog/article_create_form.html' #Associateform.instance.userwithself.request.user defform_valid(self,form): form.instance.author=self.request.user returnsuper().form_valid(form)
何时使用save_m2m方法及如何使用
save_m2m方法只用来存储多对多的关系。当你同时满足下面两个条件时,你需要使用此方法。如果你直接使用save()或form_valid()方法,是可以直接存储多对多(m2m)关系的,不需要用save_m2m。
你使用了save(commit=False)方法
你的model里有多对多的关系(比如tags)
假设我们文章模型里有tags这个多对多的字段,我们的article_create方法需要增加一行。
defarticle_create(request): ifrequest.method=='POST': form=ArticleForm(request.POST) ifform.is_valid(): article=form.save(commit=False) #commit=FalsetellsDjangothat"Don'tsendthistodatabaseyet. article.author=request.user#Settheuserobjecthere article.save()#NowyoucansendittoDB form.save_m2m() returnHttpResponseRedirect("/blog/") else: form=ArticleForm() returnrender(request,'blog/article_create_form.html',{'form':form})
以上这篇Django数据库操作之save与update的使用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。