9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Django Rest Framework】Django-Filterを使ってフィルタ機能をカスタマイズする

概要

 この記事は初心者の自分がRESTfulなAPIとswiftでiPhone向けのクーポン配信サービスを開発した手順を順番に記事にしています。技術要素を1つずつ調べながら実装したため、とても遠回りな実装となっております。

 前回の Django Rest Framework で 特定のデータだけレスポンスするようにフィルタを設定する で、 Generic Filtering を使って指定したフィールドのパラメータに一致するデータをフィルタリングできました。しかしこの方法では指定したパラメータに対して 「以上」、「以下」という条件でフィルタリングする事が出来ません。

そこで今回は日付について「〜より前」「〜より後」といった条件で有効期限を判定するフィルタ機能を実装します。

Django-Filterをインストールされていない場合は前回の記事を参考にインストールしてください。

参考

環境

Mac OS 10.15
VSCode 1.39.2
pipenv 2018.11.26
Python 3.7.4
Django 2.2.6

手順

  • views.py にFilterSetのクラスを作る
  • 既存のViewSetでFilterSetを呼ぶ処理を追加
  • 試してみる

views.py にFilterSetのクラスを作る

 django_filter の FilterSetクラスを継承してオリジナルのフィルターセットを作ります。
まずFilterSetクラスをインポートするための処理を追加します。


from django_filters import rest_framework as filters

次に、ViewSetのクラスの前にオリジナルのフィルターセットを実装します。


class CustomFilter(filters.FilterSet):
    # フィルタの定義
    deadline = filters.DateFilter(field_name='deadline', lookup_expr='gte')

    class Meta:
        model = Coupon
        fields = ['deadline'] #定義したフィルタを列挙

下記の部分がフィルタの設定になります。今回はDateFilterを使いますが、他にも文字列のフィルターや数値のフィルターなど、沢山あります。詳しくは公式ドキュメントで!


deadline = filters.DateFilter(field_name='deadline', lookup_expr='gte')

補足
上記の field_name = ‘ ‘ は フィルタリングしたいモデルフィールドの名前を指定します。ここへ名前を指定しない場合はフィルタ定義の名前(上記のコードだと deadline の部分)がフィルタリング対象のモデルフィールドの名前として扱われます。

(サンプルコードには field_name を指定していますが、フィルタ定義の名前と同じであれば実は不要です)

リクエストする際のパラメータ名はフィルタ定義の名前になります。つまり、リクエストする際のパラメータ名をモデルフィールドの名前と異なる名前にしたい場合は field_name の設定が必要です。

下記のmodel = ~には、フィルタリングしたデータのモデル名を設定します。
Fields = [~]には、フィルタ定義の名前を列挙します。


    class Meta:
        model = Coupon
        fields = ['deadline']

既存のViewSetでFilterSetを呼ぶ処理を追加

上記で実装したフィルタクラスをfilter_classとして呼ぶだけです。


filter_class = CustomFilter

試してみる

見積5分 → 5分

リクエストパラメータとして、クーポンの有効期限を示す deadline を指定しない場合と、する場合で GETできるデータの違いを比較します。

パラメータ deadline を指定しない場合

リクエスト

curl -X GET http://127.0.0.1:8000/api/coupons/

レスポンス

[{"id":1,"code":"0001","benefit":"お会計から1,000円割引","explanation":"5,000円以上ご利用のお客様限定。他クーポンとの併用不可。","store":"全店","start":"2019-10-01","deadline":"2019-12-31","status":true},{"id":2,"code":"0002","benefit":"お会計を10%オフ!","explanation":"他クーポンとの併用不可","store":"有楽町店","start":"2019-10-01","deadline":"2019-12-31","status":true},{"id":3,"code":"0003","benefit":"【ハロウィン限定】仮装して来店すると30%オフ","explanation":"全身の50%以上を仮装されているお客様限定(判断はスタッフの感覚とさせて頂きます)。他クーポンとの併用不可","store":"神田店","start":"2019-10-31","deadline":"2019-10-31","status":true},{"id":4,"code":"0004","benefit":"【9月限定】お月見団子サービス","explanation":"ご希望のお客様に月見団子をプレゼント! 他クーポンとの併用可能です!","store":"全店","start":"2019-09-01","deadline":"2019-09-30","status":true},{"id":5,"code":"0005","benefit":"【雨の日限定】お会計から15%オフ","explanation":"クーポンが配信された時だけ利用可能です。他クーポンとの併用不可","store":"全店","start":"2019-10-01","deadline":"2019-12-31","status":false},{"id":6,"code":"0006","benefit":"【日曜日限定】乾杯テキーラサービス","explanation":"テキーラを人数分サービスします。他クーポンとの併用可。","store":"神田店","start":"2019-11-03","deadline":"2019-12-01","status":true},{"id":7,"code":"0007","benefit":"お会計から19%引き","explanation":"12月29日~12月31日限定。他のクーポンとの併用不可","store":"神田店","start":"2019-12-29","deadline":"2019-12-31","status":true}]

deadlineを指定する場合

リクエスト(有効期限が12月5日以降のクーポンだけリクエスト)

curl -X GET http://127.0.0.1:8000/api/coupons/?deadline=2019-12-05

レスポンス

[{"id":1,"code":"0001","benefit":"お会計から1,000円割引","explanation":"5,000円以上ご利用のお客様限定。他クーポンとの併用不可。","store":"全店","start":"2019-10-01","deadline":"2019-12-31","status":true},{"id":2,"code":"0002","benefit":"お会計を10%オフ!","explanation":"他クーポンとの併用不可","store":"有楽町店","start":"2019-10-01","deadline":"2019-12-31","status":true},{"id":5,"code":"0005","benefit":"【雨の日限定】お会計から15%オフ","explanation":"クーポンが配信された時だけ利用可能です。他クーポンとの併用不可","store":"全店","start":"2019-10-01","deadline":"2019-12-31","status":false},{"id":7,"code":"0007","benefit":"お会計から19%引き","explanation":"12月29日~12月31日限定。他のクーポンとの併用不可","store":"神田店","start":"2019-12-29","deadline":"2019-12-31","status":true}]

有効期限が12月5日以降のクーポンのみGET出来ました。

次は認証機能を実装します

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?