ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
インストールと最小構成
pip install django-filter# settings.py
INSTALLED_APPS = [
...,
'django_filters',
'rest_framework',
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
}
lookup_expr 一覧
| lookup_expr | SQL 相当 | 例(URL) |
|---|---|---|
exact | = 'foo' | ?name=foo |
iexact | 大文字小文字無視 = | ?name__iexact=FOO |
contains | LIKE '%foo%' | ?name__contains=oo |
icontains | 大文字小文字無視 LIKE | ?name__icontains=oo |
startswith | LIKE 'foo%' | ?name__startswith=Ja |
istartswith | 大文字小文字無視 | ?name__istartswith=ja |
endswith | LIKE '%foo' | ?name__endswith=son |
gt / gte | > / >= | ?price__gte=1000 |
lt / lte | < / <= | ?price__lt=5000 |
in | IN (1,2,3) | ?status__in=1,2,3 |
range | BETWEEN a AND b | ?price__range=100,500 |
isnull | IS NULL | ?deleted_at__isnull=true |
regex | 正規表現 | ?name__regex=^A.* |
date / year / month / day | 日付の部分一致 | ?created__year=2026 |
FilterSet で明示的に定義
# filters.py
import django_filters
from .models import Product
class ProductFilter(django_filters.FilterSet):
# 名前: 部分一致
name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
# 価格: 範囲指定
price_min = django_filters.NumberFilter(field_name='price', lookup_expr='gte')
price_max = django_filters.NumberFilter(field_name='price', lookup_expr='lte')
# カテゴリ: 完全一致
category = django_filters.NumberFilter(field_name='category_id', lookup_expr='exact')
# 複数カテゴリ: IN
categories = django_filters.BaseInFilter(field_name='category_id', lookup_expr='in')
# 作成日: 範囲(YYYY-MM-DD,YYYY-MM-DD)
created = django_filters.DateFromToRangeFilter(field_name='created_at')
# NULL チェック
discontinued = django_filters.BooleanFilter(field_name='discontinued_at', lookup_expr='isnull', exclude=True)
class Meta:
model = Product
fields = ['name', 'price_min', 'price_max', 'category', 'categories', 'created', 'discontinued']
ViewSet と組み合わせる
# views.py
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .models import Product
from .serializers import ProductSerializer
from .filters import ProductFilter
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = ProductFilter
クエリ例:
# 名前に "ペン" を含み、価格が 100〜500 円
curl 'http://localhost:8000/api/products/?name=ペン&price_min=100&price_max=500'
# カテゴリ 1, 2, 3 のいずれか
curl 'http://localhost:8000/api/products/?categories=1,2,3'
# 2026年1月〜3月作成
curl 'http://localhost:8000/api/products/?created_after=2026-01-01&created_before=2026-03-31'
# 廃版でないもの
curl 'http://localhost:8000/api/products/?discontinued=true'
filterset_fields による簡易宣言
FilterSet クラスを書かず、ViewSet 内で完結:
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [DjangoFilterBackend]
# シンプル: フィールド = exact マッチのみ
# filterset_fields = ['category', 'status']
# 詳細: フィールドごとに複数 lookup を許可
filterset_fields = {
'name': ['exact', 'icontains', 'startswith'],
'price': ['exact', 'gt', 'lt', 'range'],
'category': ['exact', 'in'],
'created_at': ['date', 'year', 'gte', 'lte'],
}
これで ?name__icontains=ペン, ?price__gt=500, ?created_at__year=2026 のようなクエリが自動で動きます。
カスタムフィルタ(method パラメータ)
単純 lookup では足りない複雑な条件:
from django.db.models import Q
class ProductFilter(django_filters.FilterSet):
# 名前 or 説明文を横断検索
search = django_filters.CharFilter(method='filter_search')
def filter_search(self, queryset, name, value):
return queryset.filter(
Q(name__icontains=value) | Q(description__icontains=value)
)
# 在庫あり / なし
in_stock = django_filters.BooleanFilter(method='filter_stock')
def filter_stock(self, queryset, name, value):
if value:
return queryset.filter(stock_count__gt=0)
return queryset.filter(stock_count=0)
class Meta:
model = Product
fields = ['search', 'in_stock']
ChoiceFilter / TypedChoiceFilter
class OrderFilter(django_filters.FilterSet):
STATUS_CHOICES = [
('pending', '保留中'),
('shipped', '発送済'),
('delivered', '配達完了'),
]
status = django_filters.ChoiceFilter(choices=STATUS_CHOICES)
class Meta:
model = Order
fields = ['status']
FAQ
Q: lookup_expr と filterset_fields どちらを使う?
A: 単純なら filterset_fields。フィールド名を URL と一致させたい / カスタムロジックが欲しい場合は FilterSet クラス。
Q: 結合テーブルのフィールドでフィルタしたい
A: field_name='category__name' のように __ でリレーション辿れます。
Q: GET だけでなく POST でもフィルタしたい
A: 標準は GET。POST 対応は DRF のカスタムバックエンドを書く。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- MySQL/MariaDBへの接続
- sqliteへの接続
- SELECT, INSERT, UPDATE, DELETE
- 素のSQLを直接実行する方法
- Order by DESCの指定方法
- limit, offsetの指定方法
- filterの検索オプション
- django-filterのlookup_expr検索オプション
- モデルの内部結合(1対1)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?