2016-08-02 7 views
0

DjangoアプリケーションでDjango REST Frameworkを使用してAPIを提供し、最近フィルタリングを追加しました。 UIのいくつかをサポートするために、いくつかの缶詰め/名前付きフィルタプリセットを提供できるようにしたいと考えています。たとえば、すべてのタスクのリストを表示する/api/tasksビューセットがあります。タスクの完了ステータスフィールドと完了日があります。 UIでは、不完全な、または完了したが最後の2時間以内のすべてのタスクのリストを取得できます。これはDjangoクエリーセットでは簡単ですが、DRFフィルタでは簡単ではありません。最終的な目標は/api/tasks?recentなどを取得することです。DRFキャンドフィルター - ベストプラクティス?

このようなことを行うためのベストプラクティスはありますか?私は別のクエリーセットフィールドで新しいビューセットを作成できますが、より良い方法がありますか?

編集:作業を行いますが、ちょうど不格好な感じ

class PushTaskViewSet(AuthenticatedAPIModelViewSet): 
    queryset = PushTask.objects.all() 
    serializer_class = PushTaskSerializer  
    filter_fields = ('complete', 'date_created', 'date_completed', 'progress') 

class RecentPushTaskViewSet(AuthenticatedAPIModelViewSet): 
    # Get all tasks which are either incomplete, or only recently completed 
    serializer_class = PushTaskSerializer 

    def get_queryset(self): 
     return PushTask.objects.filter(Q(complete=False) | Q(date_completed__gt=self.get_completed_threshold())) 

    def get_completed_threshold(self): 
     return datetime.now(tz=pytz.utc) - timedelta(hours=4) 

router.register(r'master-tasks', viewsets.PushTaskViewSet) 
router.register(r'recent-master-tasks', viewsets.RecentPushTaskViewSet, base_name="recent-master-tasks") 

:ここに私の現在のソリューションです。

答えて

1

DjangoFilterBackendを使用できます。詳細については、documentationを参照してください。

REST_FRAMEWORK = { 
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend', 
    ) 
} 

と、ビューでそれを使用します: インストール後django-filter libにsettings.pyファイルにDjangoFilterBackendを追加することを忘れないオブジェクトをフィルタリングする

class TaskListCreateView(ListCreateAPIView): 
    filter_backends = (DjangoFilterBackend,) 
    filter_fields = ('status',) 
    serializer_class = TaskSerializer 

代替方法が使用Filtering against query parametersです。私はそれがORサポートしていない見ることができ、また、私はシンプルなものを持って見ていた限り、本当だ(と私は疑問に言った)が、

class TaskListCreateView(ListCreateAPIView): 
    def get_queryset(self): 
     queryset = Task.objects.all() 
     status = self.request.query_params.get('status', None) 
     if status: 
      queryset = queryset.filter(status=status) 
     return queryset 
+0

:このためだけget_querysetメソッドをオーバーライドします一般的なケース。 – AnotherHowie

+0

@ AnotherHowie私は自分の答えを広げた –