距離鐵人賽完賽越來越近,今天是所有Django補充系列的完結篇。
昨天我們複習取得資料表資料的方法,並且學會如何取得特定欄或列的資料,在這篇文章中,我們將學會如何篩選(filter)和排序(order by)取出來的資料表資料。
小提醒,這邊的filter跟Django Template Tag的filter不一樣,不要搞混它們喔!
測試環境的建立參見【Day 20】if 篇,這邊就不再占用版面解釋它。
Filter
QuerySet的Filter在昨天的文章中有出現,它是用來幫我們找出符合特定條件的資料表紀錄(Record)。除了單一條件的篩選外,我們還可以透過不同的寫法,做到複數條件的篩選。
1. 單一條件的篩選
1 | .filter(欄位篩選條件) |
假設我們要找出Members資料表firstname欄位是Jimmy的資料,則可以在members/views.py的testing方法這麼寫 :
1 | #其他內容不要動 |
Members.objects.filter(firstname=‘Jimmy’).values()
翻譯成SQL如下 :
SELECT * FROM members WHERE firstname = ‘Jimmy’ ;
接著把testing.html修改成下面這樣 :
1 | <table border='1'> |
啟動Server並前往網址127.0.0.1/members/testing檢視結果。
可以清楚看到firstname欄位是Jimmy的資料紀錄(Record)被取出來。

2. 複數條件的篩選
filter()方法不只可以接受單一引數,它可以接受複數引數,這也意味著我們可以做複數條件的資料篩選。
-
透過格式實現
And的條件篩選1
.filter(篩選條件1, 篩選條件2, ...)
假設我們現在想要篩選
Members資料表的lastname欄位是Huang且id欄位是7的資料紀錄,我們可以這樣改寫members/views.py的testing方法 :1
2
3
4
5
6
7
8#其他內容不要動
def testing(request):
mydata = Members.objects.filter(lastname='Huang', id='7').values()
template = loader.get_template('testing.html')
context = {
'mymembers': mydata,
}
return HttpResponse(template.render(context, request))Members.objects.filter(lastname=‘Huang’, id=‘7’).values()
翻譯成SQL如下 :
SELECT * FROM members WHERE lastname = ‘Huang’ AND id = 7;透過
,分隔2個欄位篩選條件,我們成功實現And的條件篩選。這邊testing.html的內容不用更動,直接刷新瀏覽器,就可以看到被篩選出的資料紀錄(Record)。
-
透過格式實現
Or的條件篩選1
.filter(篩選條件1) | .filter(篩選條件2)
假設我們現在想要篩選
Members資料表的lastname欄位是Huang或者id欄位是6的資料紀錄,我們可以這樣改寫members/views.py的testing方法 :1
2
3
4
5
6
7
8#其他內容不要動
def testing(request):
mydata = Members.objects.filter(lastname='Huang').values() | Members.objects.filter(id='6').values()
template = loader.get_template('testing.html')
context = {
'mymembers': mydata,
}
return HttpResponse(template.render(context, request))Members.objects.filter(lastname=‘Huang’).values() | …
翻譯成SQL如下 :
SELECT * FROM members WHERE lastname = ‘Huang’ OR id = 6;上面的寫法雖然可以成功篩選資料,但它真的是太冗長了,我們可以透過
Q expressions換一種寫法。記得先from django.db.models import Q才能使用Q expression喔!mydata = Members.objects.filter(Q(firstname='Huang') | Q(id='6')).values()這邊不會說明
Q expressions是什麼,現階段只要知道它可以把篩選條件的寫法簡化就好。透過
|分隔2個欄位篩選條件,我們成功實現Or的條件篩選。這邊testing.html的內容不用更動,直接刷新瀏覽器,就可以看到被篩選出的資料紀錄(Record)。
3. 預設的條件篩選方法
1 | .filter(欄位名稱__欄位篩選方法=資料值); #注意,它是2個_ |
假設我們想要篩選Members資料表的firstname欄位,並且開頭要是L的資料紀錄,可以怎麼做呢? 我們可以使用Django預先定義好的寫法firstname__startswith='L',並改寫members/views.py的testing方法 :
1 | #其他內容不要動 |
這邊testing.html的內容不用更動,直接刷新瀏覽器,就可以看到被篩選出的資料紀錄(Record)。

其他預設的條件篩選方法還有很多,有興趣的話可以自行上網找資料。
Order By
最後,我們要對從Members資料表取出的資料紀錄(Record)做排序囉!
-
單一欄位遞增排序
1
.order_by(欄位名稱)
假設我們想要想要依據
Members資料表的firstname欄位遞增排序,我們可以這樣改寫members/views.py的testing方法 :1
2
3
4
5
6
7
8#其他內容不要動
def testing(request):
mydata = Members.objects.all().order_by('firstname').values()
template = loader.get_template('testing.html')
context = {
'mymembers': mydata,
}
return HttpResponse(template.render(context, request))這邊
testing.html的內容不用更動,直接刷新瀏覽器,就可以看到排序後的資料紀錄(Record)。 下面的資料紀錄依照firstname欄位被遞增排序好了。
-
單一欄位遞減排序
1
.order_by(-欄位名稱)
假設我們想要想要依據
Members資料表的firstname欄位遞減排序,我們可以這樣改寫members/views.py的testing方法 :1
2
3
4
5
6
7
8#其他內容不要動
def testing(request):
mydata = Members.objects.all().order_by('-firstname').values()
template = loader.get_template('testing.html')
context = {
'mymembers': mydata,
}
return HttpResponse(template.render(context, request))注意,要加上負號
-表示遞減排序。這邊
testing.html的內容不用更動,直接刷新瀏覽器,就可以看到排序後的資料紀錄(Record)。 下面的資料紀錄依照firstname欄位被遞減排序好了。
-
複數欄位排序(遞增或遞減)
1
.order_by(欄位名稱, 欄位名稱, ...)
假設我們想要想要依據
Members資料表的firstname欄位遞增排序,再依據id欄位遞減排序,我們可以這樣改寫members/views.py的testing方法 :1
2
3
4
5
6
7
8#其他內容不要動
def testing(request):
mydata = Members.objects.all().order_by('firstname', '-id').values()
template = loader.get_template('testing.html')
context = {
'mymembers': mydata,
}
return HttpResponse(template.render(context, request))這邊
testing.html的內容不用更動,直接刷新瀏覽器,就可以看到排序後的資料紀錄(Record)。 下面的資料紀錄先依照firstname欄位被遞增排序,再依照id欄位被遞減排序。
今天我們對於資料表紀錄(
Record)的篩選(filter)和排序(order by)有更進一步的認識。明天會介紹如何透過Bootstrap框架來簡單地美化網頁。