1. 程式人生 > 程式設計 >Django資料庫操作之save與update的使用

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` = 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,u'',u'
',12,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,{'form': form})

以上這篇Django資料庫操作之save與update的使用就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。