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` = 481 LIMIT 1; 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-02 17:43:53 WHERE `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-02 1
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 0 WHERE (`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's useful when you get most of your model data from a form, but need to populate some null=False fields with non-form data. Saving with commit=False gets you a model object, then you can add your extra data and save it.
当你通过表单获取你的模型数据,但是需要给模型里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 .models import Article from django.forms import ModelForm from django.http import HttpResponseRedirect from django.shortcuts import render class ArticleForm(ModelForm): class Meta: model = Article exclude = ['author'] def article_create(request): if request.method == 'POST': form = ArticleForm(request.POST) if form.is_valid(): article = form.save(commit=False) # commit=False告诉Django先不提交到数据库. article.author = request.user # 添加额外数据 article.save() # 发送到数据库 return HttpResponseRedirect("/blog/") else: form = ArticleForm() return render(request, 'blog/article_create_form.html', {'form': form})
如果你使用Django自带的基于类的视图(CBV), 你可以使用form_valid方法完成上述同样的操作。具体代码如下。
from django.views.generic.edit import CreateView from .models import Article from django.forms import ModelForm # Create your views here. class ArticleForm(ModelForm): class Meta: model = Article exclude = ['author'] class ArticleCreateView(CreateView): model = Article form_class = ArticleForm template_name = 'blog/article_create_form.html' # Associate form.instance.user with self.request.user def form_valid(self, form): form.instance.author = self.request.user return super().form_valid(form)
何时使用save_m2m方法及如何使用
save_m2m方法只用来存储多对多的关系。当你同时满足下面两个条件时,你需要使用此方法。如果你直接使用save()或form_valid()方法,是可以直接存储多对多(m2m)关系的,不需要用save_m2m。
你使用了save(commit=False)方法
你的model里有多对多的关系(比如tags)
假设我们文章模型里有tags这个多对多的字段,我们的article_create方法需要增加一行。
def article_create(request): if request.method == 'POST': form = ArticleForm(request.POST) if form.is_valid(): article = form.save(commit=False) # commit=False tells Django that "Don't send this to database yet. article.author = request.user # Set the user object here article.save() # Now you can send it to DB form.save_m2m() return HttpResponseRedirect("/blog/") else: form = ArticleForm() return render(request, 'blog/article_create_form.html', {'form': form})
以上这篇Django数据库操作之save与update的使用就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]