初めてdjango-rest-frameworkを利用したシステムを作ることになった。
django-filterと言われるものが有るらしいので入れた際に時間がかかった点について書いていこうと思う。
https://django-filter.readthedocs.io/en/stable/guide/install.html
やりたかったこと
Customerモデルを検索するときにcustomerNameに値を渡したら、customerNameに該当するものとfuriganaに該当するデータを出力したかった。
結果
filters.FilterSetにカスタムのやつ作る
コマンドプロンプト
$ pip install django-filter
djangoのsettings.pyのINSTALLED_APPS追記する。
settings.py
INSTALLED_APPS = [
...
'django_filters',
]
Djangoにアプリを追加したり色々、ここらへんは省略。
以下はmodelsやview、serializerの設定を記載します。
models.py
class Customer(models.Model):
customerCode = models.IntegerField("得意先コード")
customerName = models.CharField("得意先名", max_length=100)
furigana = models.CharField("ふりがな", max_length=100, blank=True, null=True)
def __str__(self):
return self.name
serializers.py
from rest_framework import serializers
from .models import Customer
class CustomerSerializer(serializers.ModelSerializer):
class Meta:
model = Customer
fields = '__all__'
views.py
from rest_framework import viewsets
from django_filters import rest_framework as filters
from django.db.models import Q
from .serializers import CustomerSerializer
from .models import Customer
class CustomerFilter(filters.FilterSet):
# フィルタの定義
customerCode = filters.NumberFilter(lookup_expr='exact')
customerName = filters.CharFilter(method='myCustomNameFilter')
furigana = filters.CharFilter(lookup_expr='contains')
class Meta:
model = Customer
# フィルタを列挙する。
# デフォルトの検索方法でいいなら、モデルフィールド名のフィルタを直接定義できる。
fields = ['customerCode','customerName ', 'furigana']
def myCustomNameFilter(self,queryset,name,value):
#ここでOR検索を入れる。fieldsのcustomerNameに入ってきた値を利用
return Customer.objects.filter(Q(customerName__startswith=value)|Q(furigana__startswith=value))
class CustomerViewSet(viewsets.ModelViewSet):
queryset = Customer.objects.all()
serializer_class = CustomerSerializer
filter_class = CustomerFilter
urls.py
from rest_framework import routers
from .views import CustomerViewSet
router = routers.DefaultRouter()
router.register("customers",CustomerViewSet)