タイムスタンプフィールドのあるモデルがあります。
models.py
class Event(models.Model):
event_type = models.CharField(
max_length=100,
choices=EVENT_TYPE_CHOICES,
verbose_name=_("Event Type")
)
event_model = models.CharField(
max_length=100,
choices=EVENT_MODEL_CHOICES,
verbose_name=_("Event Model")
)
timestamp = models.DateTimeField(auto_now=True, verbose_name=_("Timestamp"))
次に、Django-rest-frameworkを使用して、このクラスのAPIエンドポイントを作成します。Django-filterは、次のようなフィルタリング機能を提供します。
from .models import Event
from .serializers import EventSerializer
from rest_framework import viewsets, filters
from rest_framework import renderers
from rest_framework_csv import renderers as csv_renderers
class EventsView(viewsets.ReadOnlyModelViewSet):
"""
A read only view that returns all audit events in JSON or CSV.
"""
queryset = Event.objects.all()
renderer_classes = (csv_renderers.CSVRenderer, renderers.JSONRenderer)
serializer_class = EventSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('event_type', 'event_model', 'timestamp')
次の設定で:
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',),
}
event_type
とevent_model
でフィルタリングできますが、タイムスタンプフィールドでフィルタリングできません。基本的に、次のようなAPI呼び出しを行います。
AuditEvent.objects.filter(timestamp__gte='2016-01-02 00:00+0000')
これは私が次のようにできると期待します:
response = self.client.get("/api/v1/events/?timestamp=2016-01-02 00:00+0000", **{'HTTP_ACCEPT': 'application/json'})
それは不正確ですが。特定の値以上のタイムスタンプを持つすべてのオブジェクトを返すAPI呼び出しを行うにはどうすればよいですか?
Flaimingの答えをさらに詳しく説明すると、ISO日時形式でのみフィルタリングする場合は、デフォルトを上書きして常にIsoDateTimeFilter
を使用するようにすると役立ちます。これは、フィルターセットごとに行うことができます。
from Django.db import models as Django_models
import Django_filters
from rest_framework import filters
from rest_framework import viewsets
class EventFilter(filters.FilterSet):
class Meta:
model = Event
fields = {
'timestamp': ('lte', 'gte')
}
filter_overrides = {
Django_models.DateTimeField: {
'filter_class': Django_filters.IsoDateTimeFilter
},
}
class EventsView(viewsets.ReadOnlyModelViewSet):
...
filter_class = EventFilter
その後、各ルックアップ式と各フィールドに異なるフィルターを設定することを心配する必要はありません。
次のように特定の FilterSet
を作成できます。
import Django_filters
from rest_framework import filters
from rest_framework import viewsets
class EventFilter(filters.FilterSet):
timestamp_gte = Django_filters.DateTimeFilter(name="timestamp", lookup_expr='gte')
class Meta:
model = Event
fields = ['event_type', 'event_model', 'timestamp', 'timestamp_gte']
class EventsView(viewsets.ReadOnlyModelViewSet):
...
filter_class = EventFilter
"/api/v1/events/?timestamp_gte=2016-01-02"
EDIT:明確にするために、この例では Django-filter ライブラリを使用しています。
IsoDateTimeFilter
は、入力形式について非常にうるさいです。の代わりに:
使用する:
より良い方法は、get_queryset関数で日時をフィルタリングすることです
def get_queryset(self):
queryset = Event.objects.all()
start_date = self.request.query_params.get('start_date', None)
end_date = self.request.query_params.get('end_date', None)
if start_date and end_date:
queryset = queryset.filter(timstamp__range=[start_date, end_date])