Django數(shù)據(jù)庫(kù)操作之save與update的使用
Python框架Django有著諸多優(yōu)點(diǎn),它提供的models可以讓開發(fā)者方便地操作數(shù)據(jù)庫(kù),但正是由于對(duì)上層的良好的封裝,使得提升數(shù)據(jù)庫(kù)操作性能必須要清楚地知道Django的數(shù)據(jù)庫(kù)操作到底執(zhí)行了哪些SQL語(yǔ)句。
例如數(shù)據(jù)更新操作,對(duì)單條記錄,可以使用save或者是update兩種方式
在Django工程下的settings.py下將log設(shè)置為DEBUG,即可查看save和update分別執(zhí)行了哪些SQL語(yǔ)句
如有一張表名叫做Example
使用save:
k = Example.objects.get(id=481) k.total_calories = 12 k.save()
執(zhí)行的SQL語(yǔ)句如下所示:
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()的時(shí)候提交更新的內(nèi)容,發(fā)現(xiàn)更新的時(shí)候把Example中的有字段都SET賦值的一次
使用update
Example.objects.filter(id=481).update(total_calories = 10)
執(zhí)行的SQL語(yǔ)句是:
UPDATE `Example` SET `total_calories` = 1 0 WHERE (`Example`.`user_id` = asdfasdf AND `Example`.`id` = 481 ); args=(10, u'asdfasdf', 481)
這條SQL語(yǔ)句簡(jiǎn)短而且執(zhí)行速度要優(yōu)于使用save的速度。
從SQL的執(zhí)行情況來(lái)看,使用upate是要優(yōu)于save方式的。
從使用情境上看,update更加適用于批量數(shù)據(jù)更新,而save則更適合當(dāng)然也只適合做單條記錄的數(shù)據(jù)更新操作了。
在使用Django的數(shù)據(jù)模型操作數(shù)據(jù)庫(kù)時(shí),了解這些底層的SQL操作很有必要。
補(bǔ)充知識(shí):如何理解Django的save(commit=False)方法和save_m2m()方法
什么時(shí)候使用save(commit=False)方法,save_m2m方法以及如何使用是Django表單forms進(jìn)階必需了解的知識(shí)。我們今天就帶你來(lái)看一看。
何時(shí)使用save(commit=False)方法
Stackoverflow上其實(shí)已經(jīng)有了一段非常精煉的答案。英文原文如下,我把它翻譯了一下:
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.
當(dāng)你通過(guò)表單獲取你的模型數(shù)據(jù),但是需要給模型里null=False字段添加一些非表單的數(shù)據(jù),該方法會(huì)非常有用。如果你指定commit=False,那么save方法不會(huì)理解將表單數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù),而是給你返回一個(gè)當(dāng)前對(duì)象。這時(shí)你可以添加表單以外的額外數(shù)據(jù),再一起存儲(chǔ)。
save(commit=False)方法實(shí)際應(yīng)用案例
下面我們來(lái)看一個(gè)實(shí)際應(yīng)用案例。我們創(chuàng)建了一個(gè)叫文章Article的模型,里面包含title, body和作者author等多個(gè)字段,其中author字段非空null=False。我們由Article模型創(chuàng)建了一個(gè)ArticleForm表單,可以讓用戶發(fā)表新文章,但是我們故意把a(bǔ)uthor字段除外了,因?yàn)槲覀儾幌M脩艟庉嬜髡摺?/p>
最后用戶提交的表單數(shù)據(jù)里肯定沒有author,當(dāng)這樣的數(shù)據(jù)提交到數(shù)據(jù)庫(kù)時(shí)肯定會(huì)有問(wèn)題的。所以我們先通過(guò) article = form.save(commit=False)創(chuàng)建article實(shí)例,此時(shí)讓Django先不要發(fā)送數(shù)據(jù)到數(shù)據(jù)庫(kù),等待我們把a(bǔ)uthor添加好后,再把數(shù)據(jù)一起存儲(chǔ)到數(shù)據(jù)庫(kù)中。
下面是視圖文件views.py的代碼。最重要的是ArticleForm構(gòu)成和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先不提交到數(shù)據(jù)庫(kù). article.author = request.user # 添加額外數(shù)據(jù) article.save() # 發(fā)送到數(shù)據(jù)庫(kù) 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)
何時(shí)使用save_m2m方法及如何使用
save_m2m方法只用來(lái)存儲(chǔ)多對(duì)多的關(guān)系。當(dāng)你同時(shí)滿足下面兩個(gè)條件時(shí),你需要使用此方法。如果你直接使用save()或form_valid()方法,是可以直接存儲(chǔ)多對(duì)多(m2m)關(guān)系的,不需要用save_m2m。
你使用了save(commit=False)方法
你的model里有多對(duì)多的關(guān)系(比如tags)
假設(shè)我們文章模型里有tags這個(gè)多對(duì)多的字段,我們的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數(shù)據(jù)庫(kù)操作之save與update的使用就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)獲取當(dāng)前日期的所屬信息
在Python中,處理日期和時(shí)間是一個(gè)常見的任務(wù),它涉及到許多方面,例如獲取日期的年、月、日、星期幾等等,本文將詳細(xì)介紹如何使用Python來(lái)獲取當(dāng)前日期的各種相關(guān)信息,需要的可以了解下2024-01-01python代碼實(shí)現(xiàn)圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python代碼實(shí)現(xiàn)圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11Python?pandera數(shù)據(jù)驗(yàn)證和清洗的庫(kù)
為了確保數(shù)據(jù)的質(zhì)量,Python Pandera 庫(kù)應(yīng)運(yùn)而生。本文將深入介紹 Python Pandera,這是一個(gè)用于數(shù)據(jù)驗(yàn)證和清洗的庫(kù),并提供豐富的示例代碼,幫助大家充分利用它來(lái)提高數(shù)據(jù)質(zhì)量2024-01-01Pycharm遠(yuǎn)程調(diào)試openstack的方法
這篇文章主要為大家詳細(xì)介紹了Pycharm遠(yuǎn)程調(diào)試openstack的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11掌握python polars庫(kù)進(jìn)行高效高速的數(shù)據(jù)處理。
這篇文章主要介紹了python polars庫(kù)進(jìn)行高效高速的數(shù)據(jù)處理技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01python Aligo庫(kù)設(shè)置json路徑使用詳解
這篇文章主要為大家介紹了python Aligo庫(kù)設(shè)置json路徑使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11用Python實(shí)現(xiàn)最速下降法求極值的方法
今天小編就為大家分享一篇用Python實(shí)現(xiàn)最速下降法求極值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-07-07