2016-05-12 111 views
4

我有一些模型時間戳字段:Django - 如何使用Django Rest Framework按日期過濾?

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的框架來創建一個API端點這個類,Django的過濾器提供過濾功能如下:

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_typeevent_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'}) 

雖然這incorect。我如何進行API調用,返回時間戳大於或等於某個值的所有對象?

回答

2

您可以創建特定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"

編輯篩選:我想弄清楚,這個例子使用django-filter庫。

+0

嗯,我我仍然得到0響應,當我應該得到1.我試過使用'django_filters.DateTimeFilter'和'django_filters.IsoDateTimeFilter'。任何想法,爲什麼這可能是這種情況? – orange1

5

要擴展Flaming的答案,如果您只想通過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 

然後,您不必擔心爲每個查找表達式和每個字段設置不同的過濾器。

1

IsoDateTimeFilter對輸入格式非常挑剔;而不是:

  • 2016年1月2日00:00 + 0000

使用:

  • 2016-01-02T00:00:00Z
相關問題