距離鐵人賽完賽越來越近,今天是所有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
框架來簡單地美化網頁。