iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 13
1

接續之前的Django內容
今天來聊聊QuerySets的操作
先看一下官方的解釋:

一個 QuerySet,大體上來說,是一個充滿了 Model 物件的清單。QuerySet 允許你從資料庫中讀取資料,也可以對資料做篩選或排序。

基本上就是實作ORM的模組,例如Rails的ActiveRecord
方便我們與資料互動
今天我們會透過shell操作
首先打開shell

$ python manage.py shell
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 00:54:21) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

就會進到python的shell環境
與Rails的console不同,shell並不會自動引入所有model或lib
所以當你取用之前,記得要自己引入
這點我覺得相當的不方便(扣一分)

檢視所有物件

比方說我想要看看所有的Post

>>> Post.objects.all()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
NameError: name 'Post' is not defined

他會告訴我Post尚未定義
必須要手動引入

>>> from blog.models import Post
>>> Post.objects.all()
[<Post: my first post>]

這個時候才會順利回傳
順便比較一下Rails的console

$ Post.all

我個人是覺得簡單且直觀很多

新增物件

假如我們想要新增一個post
首先必須要得到一個user,因為post必須屬於一個user
所以我們要先得到一個user
在那之前,我們還要先引入user(有夠麻煩)

# 引入user
>>> from django.contrib.auth.models import User
# 查詢user,當然如果你知道user的名稱,也可以跳過這一步
>>> User.objects.all()
[<User: bater>]
# 將user命名為一個變數
>>> user = User.objects.get(username='bater')
# 新增post
>>> Post.objects.create(author = user, title = 'Sample title', text = 'Test')
# 確認一下剛剛新增的內容
>>> Post.objects.all()
[<Post: Sample title>]

條件選取

實務上我們很少會需要所有的物件
都會有一些條件
這時我們可以利用filter來過濾條件

>>> Post.objects.filter(author=user)

這樣就會回傳由user所創造的post

除了條件,如果id已知,我們也可以透過id的方式

>>> Post.objects.get(id=1)

來取得id為一的的post

排序

除了條件篩選外,我們很常也需要依照不同欄位排序
例如依照時間排序

>>> Post.objects.order_by('created_date')

如果想要反排序

>>> Post.objects.order_by('-created_date')

就可以得到你想要的內容
記得這邊後面的條件篩選、排序是可以疊加的
所以你可以寫出例如像下面的查詢:

>>> Post.objects.filter(author=user).order_by('created_date')

除了get方法以外,因為那是取得物件本身
而物件自身是不能夠再排序的
會得到這樣的錯誤

>>> Post.objects.get(id=1).order_by('created_date')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Post' object has no attribute 'order_by'

今天就先到這邊吧!

參考資料


上一篇
2017年TIOBE程式語言排行結果雜談
下一篇
Laravel起步走:artisan tinker操作ORM練習
系列文
新時代的網頁框架比較-- 淺談Rails、Django、Phoenix、Laravel31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
froce
iT邦大師 1 級 ‧ 2017-12-18 08:53:27
>>> from blog.models import Post
>>> Post.objects.all()

這個要補充一下為什麼Django要這麼麻煩。
1.在python的慣例是沒有用到的東西不import,這是個好習慣,通常compiler在你import沒用過的lib時候會跳警告。有些語言像go甚至就直接跳錯誤了。

2.Django在剛學的時候,我也覺得幹麻都要多寫objects,後來知道這是Django設計的一個功能,叫 Manager,用途是用來自訂預設的filter。
例如說我有一個model叫USERINFO,常常要把男性都挑出來。那我在models.py寫一個manager叫isMale,這樣可以透過USERINFO.isMale和USERINFO.objects去把是男性的和全部的資料叫出來。
不過這在大型專案比較會用到,中小型的確不常用。

Bater iT邦新手 4 級 ‧ 2017-12-18 09:54:26 檢舉

感謝回饋分享!

我要留言

立即登入留言