LoginSignup
8
8

More than 3 years have passed since last update.

Django Rest Framework で 特定のデータだけレスポンスするようにフィルタを設定する

Last updated at Posted at 2020-01-03

概要

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

前回の Django Rest Framework で RESTful な APIを作成する でRest API の基本的な仕組みが出来上がりました。次は、条件の合致するデータをリクエストパラメータでフィルタできるように改造します。

django-rest-framework で構築したAPIにフィルタリングを実装するには、Generic Filtering というのが便利らしいので、それを使う方法で実装します。

参考

環境

Mac OS 10.15
VSCode 1.39.2
pipenv 2018.11.26
Python 3.7.4
Django 2.2.6

手順

  • django-filter をインストール
  • フィルタが使えるように setting.py に追記
  • views.py にfilter_fields を追記する
  • 試してみる

django-filter をインストールする

pipenvで作ったpythonのプロジェクト(仮想環境)にdjango-filter をインストールします。pipenvのシェルに入り、下記のインストールのコマンドを実行。

$ pipenv install django-filter

Pipfileを確認すると、[packages]に django-filter が追加されています。

(amiApp) bash-3.2$ cat Pipfile
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
django = "*"
djangorestframework = "*"
django-filter = "*"

[requires]
python_version = "3.7"

フィルタが使えるように setting.py に追記

ami_coupon_api/setting.pyINSTALLED_APPS に django_filters を追記

ami_coupon_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'coupon',
    'rest_framework',
    'django_filters', # 追加した

次に、ami_coupon_api/setting.pyREST_FRAMEWORK = {} の項目を作って、フィルタが使えるように下記の設定を追加します。

ami_coupon_api/settings.py

REST_FRAMEWORK = {
    #フィルタを追加
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

views.py にfilter_fields を追記する

 CouponViewSetクラスでfilter_fieldsを呼び出し、フィルタしたいcouponモデルのモデルフィールド名(couponテーブルの項目)をfilter_fieldsの引数に設定するだけです。複数の設定も可能です。filter_fieldsに設定したフィールド名を使ってレスポンスするデータのフィルタリングが行えます。

coupon/views.py

class CouponViewSet(viewsets.ModelViewSet):
    queryset = Coupon.objects.all()
    serializer_class = CouponSerializer
    filter_fields = ('status','code') #追加した

試してみる

curl コマンドでリクエストしてみます。URLの末尾に ?[条件] を付けます。条件の部分は、filter_fieldsに設定したモデルフィールド名を使います。

例えば、モデルフィールドのstatusが "false" のクーポンだけGETしたい場合はURLの末尾に?status=falseを付けて下記のようにリクエストします。

curl -X GET http://127.0.0.1:8000/api/coupons/?status=false

分かりにくいですが、下記の通りstatusfalseになっているid=5のクーポンのみGET出来ました。


[{"id":5,"code":"0005","benefit":"【雨の日限定】お会計から15%オフ","explanation":"クーポンが配信された時だけ利用可能です。他クーポンとの併用不可","store":"全店","start":"2019-10-01","deadline":"2019-12-31","status":false}]


filter_fieldsにはcodeもフィルタ対象のフィールド名として設定しているので、codeでフィルタする場合も試してみます。

例えば、codeが0007のクーポンだけGETするリクエストはURLの末尾に?code=0007を付けて下記の通りになります。

curl -X GET http://127.0.0.1:8000/api/coupons/?code=0007

codeが0007のクーポンのみGET出来ました。


[{"id":7,"code":"0007","benefit":"お会計から19%引き","explanation":"12月29日~12月31日限定。他のクーポンとの併用不可","store":"神田店","start":"2019-12-29","deadline":"2019-12-31","status":true}]


ここまでで、特定のデータ項目に完全一位するデータを取得する処理が実装できました。しかし日付のように「以前」や「以降」という条件のフィルタもクーポン配信では必要になります。

次は、Django-Filterを使ってフィルタのカスタマイズをします。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8