接續之前的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'
今天就先到這邊吧!
>>> 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去把是男性的和全部的資料叫出來。
不過這在大型專案比較會用到,中小型的確不常用。
感謝回饋分享!