iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Modern Web

Django 初心者之旅系列 第 28

【Day 28】Django QuerySet 補充篇(2) - Filter & Order By

  • 分享至 

  • xImage
  •  

距離鐵人賽完賽越來越近,今天是所有Django補充系列的完結篇。
昨天我們複習取得資料表資料的方法,並且學會如何取得特定欄或列的資料,在這篇文章中,我們將學會如何篩選(filter)和排序(order by)取出來的資料表資料。

小提醒,這邊的filterDjango Template Tagfilter不一樣,不要搞混它們喔!

測試環境的建立參見【Day 20】if 篇,這邊就不再占用版面解釋它。

Filter

QuerySetFilter在昨天的文章中有出現,它是用來幫我們找出符合特定條件的資料表紀錄(Record)。除了單一條件的篩選外,我們還可以透過不同的寫法,做到複數條件的篩選。

1. 單一條件的篩選

.filter(欄位篩選條件)

假設我們要找出Members資料表firstname欄位是Jimmy的資料,則可以在members/views.pytesting方法這麼寫 :

#其他內容不要動
def testing(request):
  mydata = Members.objects.filter(firstname='Jimmy').values()
  template = loader.get_template('testing.html')
  context = {
    'mymembers': mydata,
  }
  return HttpResponse(template.render(context, request))

Members.objects.filter(firstname='Jimmy').values()
翻譯成SQL如下 :
SELECT * FROM members WHERE firstname = ‘Jimmy' ;

接著把testing.html修改成下面這樣 :

<table border='1'>
  <tr>
    <th>Id</th>
    <th>Firstname</th>
    <th>Lastname</th>
  </tr>
  {% for x in mymembers %}
    <tr>
      <td>{{ x.id }}</td>
      <td>{{ x.firstname }}</td>
      <td>{{ x.lastname }}</td>
    </tr>
  {% endfor %}
</table>

啟動Server並前往網址127.0.0.1/members/testing檢視結果。
可以清楚看到firstname欄位是Jimmy的資料紀錄(Record)被取出來。

2. 複數條件的篩選

filter()方法不只可以接受單一引數,它可以接受複數引數,這也意味著我們可以做複數條件的資料篩選。

  • 透過格式實現And的條件篩選

    .filter(篩選條件1, 篩選條件2, ...)
    

    假設我們現在想要篩選Members資料表的lastname欄位是Huangid欄位是7的資料紀錄,我們可以這樣改寫members/views.pytesting方法 :

    #其他內容不要動
    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的條件篩選

    .filter(篩選條件1) | .filter(篩選條件2)
    

    假設我們現在想要篩選Members資料表的lastname欄位是Huang或者id欄位是6的資料紀錄,我們可以這樣改寫members/views.pytesting方法 :

    #其他內容不要動
    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. 預設的條件篩選方法

.filter(欄位名稱__欄位篩選方法=資料值); #注意,它是2個_

假設我們想要篩選Members資料表的firstname欄位,並且開頭要是L的資料紀錄,可以怎麼做呢? 我們可以使用Django預先定義好的寫法firstname__startswith='L',並改寫members/views.pytesting方法 :

#其他內容不要動
def testing(request):
      mydata = Members.objects.filter(firstname__startswith='L')
      template = loader.get_template('testing.html')
      context = {
        'mymembers': mydata,
      }
      return HttpResponse(template.render(context, request))

這邊testing.html的內容不用更動,直接刷新瀏覽器,就可以看到被篩選出的資料紀錄(Record)。

其他預設的條件篩選方法還有很多,有興趣的話可以自行上網找資料。

Order By

最後,我們要對從Members資料表取出的資料紀錄(Record)做排序囉!

  • 單一欄位遞增排序

    .order_by(欄位名稱)
    

    假設我們想要想要依據Members資料表的firstname欄位遞增排序,我們可以這樣改寫members/views.pytesting方法 :

    #其他內容不要動
    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欄位被遞增排序好了。

  • 單一欄位遞減排序

    .order_by(-欄位名稱)
    

    假設我們想要想要依據Members資料表的firstname欄位遞減排序,我們可以這樣改寫members/views.pytesting方法 :

    #其他內容不要動
    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欄位被遞減排序好了。

  • 複數欄位排序(遞增或遞減)

    .order_by(欄位名稱, 欄位名稱, ...)
    

    假設我們想要想要依據Members資料表的firstname欄位遞增排序,再依據id欄位遞減排序,我們可以這樣改寫members/views.pytesting方法 :

    #其他內容不要動
    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框架來簡單地美化網頁。


上一篇
【Day 27】Django QuerySet 補充篇(1) - Introduction & Get Data
下一篇
【Day 29】Django 網頁美化篇 - Ctrl+C/V 的魔法
系列文
Django 初心者之旅31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言