django-filterで同じ誕生日の人を検索したい!


はじめに

この記事はDjango Advent Calendar 2020 9日目の記事です。
2年連続2回目の参加です。

django-filterを使って同じ誕生日の人(月日が同じ)を取得したかった。

サンプルを作りました。
django-filterで同じ誕生日の人を検索するサンプル

生年月日をDateFieldで持っているので、そのままdjango-filterを使うとこんな感じ↓


生年月日全部同じ人ではなく、誕生日の年月が同じ人を取得したいのですが、これだと「日付を正しく入力してください」となります。
YYYY-MM-DDの形式で入力してないからですね。

DateFieldの月日だけを検索するためには、(api)/views.pyにフィルタセットを作成します。

(api)/views.py
from django_filters import rest_framework as filters
from rest_framework import viewsets

from sample.models import Samplepeople
from sampleapi.serializers import SamplepeopleSerializers

# フィルタセット
class SampleFilter(filters.FilterSet):
    # Date型の月、日をそれぞれ検索できるようにする
    birthday_month = filters.NumberFilter(field_name='date_of_birth', lookup_expr='month')
    birthday_day = filters.NumberFilter(field_name='date_of_birth', lookup_expr='day')

    class Meta:
        model = Samplepeople
        fields = ['id', 'name', 'kana', 'date_of_birth',]

# 通常のViewSet
class SampleViewSet(viewsets.ReadOnlyModelViewSet):

    queryset = Samplepeople.objects.all()
    serializer_class = SamplepeopleSerializers
    filter_backends = [filters.DjangoFilterBackend]
    # 上記のFilterを追加する
    filter_class = SampleFilter

フィルタセットで設定した項目が追加されます。

早速、同じ誕生日の人を検索します。

生まれた年は異なりますが、月日が同じ人が検索されました。

あとはAPI叩く際に?birthday_month=&birthday_day=に月と日をいれてあげればOKです。
これなら同じ誕生月の人を検索するのも楽々ですね。また、lookup_expr='year'を追加すれば同じ年に生まれた人を検索することもできます。

DateTimeFilterではない

DateFieldの検索だからDateTimeFilterを使うのかな?と思いましたが、最初のやつと同様に「日付を正しく入力してください」になります。
DateTimeFilterもYYYY-MM-DD(YYYY-MM-DD HH24-mm-SS)の形式で入力しないといけないからですね(1敗)

おわりに

もっといいやり方があれば教えてください。

参考