Django : 從零開始學 3 — ORM

Django

Django shell

在終端機執行以下指令會進入互動模式(像是Rails的$rails c指令):

$ python manage.py shell

載入Models

首先會需要將建立的models import

1
2
>>> from blog.models import Post
>>> from django.contrib.auth.models import User

get()

可以先看一個簡單的範例:

1
2
>>> user = User.objects.get(username='admin')
>>> user

使用get()有些注意事項,像是僅能返回「唯一」的條件,如果有多個符合則會報錯,如果 get() 發現多個對象,會引發一個 Model.MultipleObjectsReturned 異常:

1
Entry.objects.get(name="A Duplicated Name")  # raises Entry.MultipleObjectsReturned

這個比較像是Ruby on Rails的find(),不過find()的參數為要查找的對象的 ID(這裡則可以選擇),沒找到返還ActiveRecord::RecordNotFound 例外訊息。

另外一個也蠻像的,就是Rails的find_by() 則會返回符合條件的第一筆資料,沒找到返回nil(順便複習Rails?)。

filter()

返回一个新的 QuerySet,包含查詢的參數對象,如果沒找到會返回一個空的QuerySet

1
2
3
>>> post = Post.objects.filter(title='hi')
>>> post
<QuerySet [<Post: hi>]>

這就比較像Rails的where(),找到會返回 ActiveRecord::Relation 包含一個或多個與參數符合的對象,如果沒找到:會返回一個空的  ActiveRecord::Relation

filter()找不到的情況

1
2
3
>>> post = Post.objects.filter(title='aaa')
>>> post
<QuerySet []>

exclude()

排除查找的參數

1
2
3
>>> post = Post.objects.exclude(title='hi')
>>> post
<QuerySet [<Post: created from shell>]>

all()

秀出所有東西:

1
2
3
>>> posts = Post.objects.all()
>>> posts
<QuerySet [<Post: second-post>, <Post: hi>]>

可以使用for迴圈將文章標題印出來:

1
2
3
4
5
>>> for post in posts:
... print(post.title)
...
second-post
hi

新增

1
2
3
4
5
6
>>> post = Post(title='created from shell', slug='create-from-shell', body='this is body', author=user, status= 'draft')
>>> post
<Post: created from shell>
>>> post.save()
>>> posts
<QuerySet [<Post: second-post>, <Post: hi>]>

這裡需要.save() 才會將資料儲存到資料庫裡

更新

1
2
3
4
5
>>> post.title
'created from shell'
>>> post.title = 'new created from shell'
>>> post
<Post: new created from shell>

更新倒是蠻容易的,只要用個= 即可

first()

第一個對象

1
2
3
>>> post = Post.objects.all().first()
>>> post
<Post: created from shell>

last()

最後一個對象

1
2
3
4
5
6
>>> post = Post.objects.all().last()
>>> post
<Post: hi>
>>> posts = Post.objects.all()
>>> posts
<QuerySet [<Post: created from shell>, <Post: hi>]>

order_by()

1
2
3
4
5
6
>>> post = Post.objects.order_by('title')
>>> post
<QuerySet [<Post: created from shell>, <Post: hi>, <Post: second-post>]>
>>> post = Post.objects.order_by('-title')
>>> post
<QuerySet [<Post: second-post>, <Post: hi>, <Post: created from shell>]>

可以用-去調整正序或是倒序,這時返回的會是QuerySet

也可以使用索引[0],來返回指定的值:

1
2
3
>>> post = Post.objects.filter(title='hi')[0]
>>> post
<Post: hi>

這時返回的就是單一值

delete()

1
2
3
4
5
>>> post = post.filter(title='second-post')
>>> post.delete()
(1, {'blog.Post': 1})
>>> Post.objects.all()
<QuerySet [<Post: created from shell>, <Post: hi>]>

本篇文章是我由以下參考資料整理+自己繪圖而成,如果您有興趣了解更多,請參考:

參考資料:

Django doc - Making quries

Django doc - QuerySet

Udemy - Django 2 Web開發入門與實踐

評論