概要
この記事は初心者の自分が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.py
の INSTALLED_APPS
に django_filters を追記
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.py
にREST_FRAMEWORK = {}
の項目を作って、フィルタが使えるように下記の設定を追加します。
REST_FRAMEWORK = {
#フィルタを追加
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
views.py にfilter_fields を追記する
CouponViewSet
クラスでfilter_fields
を呼び出し、フィルタしたいcouponモデルのモデルフィールド名(couponテーブルの項目)をfilter_fields
の引数に設定するだけです。複数の設定も可能です。filter_fields
に設定したフィールド名を使ってレスポンスするデータのフィルタリングが行えます。
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
分かりにくいですが、下記の通りstatus
がfalse
になっている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}]
ここまでで、特定のデータ項目に完全一位するデータを取得する処理が実装できました。しかし日付のように「以前」や「以降」という条件のフィルタもクーポン配信では必要になります。