在〈Python 3 Tutorial 第八堂(2)建立 App 與模型〉中,已經撰寫了模型程式碼,並且利用 Django 的遷移(Migration)功能,自動建立了資料庫中的相關表格,接下來,我們就來操作模型與資料庫吧!
查詢全部資料
你可以鍵入 python3.5 manage.py shell
指令,這會設定 DJANGO_SETTINGS_MODULE
環境變數,讓你可以取用 Django 的 Python 模組,然後進入 Python 互動環境,在當中體驗一些 API 的使用。
一開始從 polls.models
模組中,匯入了 Question
與 Choice
類別,若想查詢全部的「問題」或「選項」,可以使用 Question.objects.all()
與 Choice.objects.all()
,也就是在類別名稱之後,接下 objects.all()
。
可以看到,你不用撰寫任何 SQL,Django 會自動幫你轉換對應的 SQL,取得結果然後包裝為物件,你不用自行進行物件與關聯式資料庫之間的對應,這樣的技術稱之為 ORM(Object-Relational Mapping),對於應用程式快速開發時非常便利,當然,目前「問題」與「選項」都沒有任何資訊,因此傳回空 list
。
資料儲存、欄位查詢與更新
接著在資料庫進行資料的儲存,直接來看看如何儲存「問題」:
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2016, 3, 5, 9, 18, 10, 991796, tzinfo=<UTC>)
>>> q.question_text = "What's up?"
>>> q.save()
>>> Question.objects.all()
[<Question: What's up?>]
>>>
因為 Question
在儲存時,必須提供時間資訊,因此從 django.utils
模組中匯入了 timezone
,要儲存一個「問題」,只要建立 Question
實例,並呼叫其 save()
就可以了,至於查詢或更新相關欄位,也只是對屬性做操作。
特定條件查詢
那麼,如果有多個「問題」,想要進行條件過濾呢?可以使用 filter
函式,例如:
>>> Question.objects.filter(id=1)
[<Question: What's up?>]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]
>>> Question.objects.filter(id=2)
[]
>>> Question.objects.filter(question_text__startswith='What')
[<Question: What's up?>]
>>>
可以看到,filter
函式會以 list
傳回符合條件的資料,如果你只想取回一筆資料,也可以使用 get
,不過,若查詢的條件不存在,get
會引發 DoesNotExist
的錯誤,例如:
>>> Question.objects.get(pub_date__year=timezone.now().year)
<Question: What's up?>
>>> Question.objects.get(id=1)
<Question: What's up?>
>>> Question.objects.get(id=2)
Traceback (most recent call last):
略...
polls.models.DoesNotExist: Question matching query does not exist.
>>> Question.objects.get(pk=1)
<Question: What's up?>
>>>
在查詢主鍵時,使用 get(id=1)
或 get(pk=1)
都可以。
建立關聯與刪除資料
一個「問題」會有多個「選項」,來看看怎麼建立兩者之間的關聯:
>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
[]
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
>>> c.question
<Question: What's up?>
>>> q.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> q.choice_set.count()
3
>>> Choice.objects.filter(question__pub_date__year=timezone.now().year)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
(1, {'polls.Choice': 1})
>>>
這些操作都不太需要多做解釋,若想進一步瞭解更多這類操作,可以參考〈Database API reference〉。