DRF罐装过滤器 - 最佳实践?

时间:2016-08-02 15:17:50

标签: python django django-rest-framework

我在我的Django应用程序中使用Django REST Framework来提供API,并且最近添加了过滤功能。为了支持UI中的一些内容,我希望能够提供一些预制/命名过滤器预设 - 例如,有一个/api/tasks视图集,可以为您提供所有任务的列表。任务具有完成的状态字段和完成日期。在用户界面中,我希望能够获取所有未完成或已完成但在过去几小时内完成的任务列表。使用Django查询集很容易,但DRF过滤器不容易 - 最终目标是能够获取/api/tasks?recent或类似的东西。

做这种事是否有最好的做法?我可以创建一个具有不同查询集字段的新ViewSet,但有更好的方法吗?

编辑:这是我目前的解决方案:

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 个答案:

答案 0 :(得分:1)

您可以使用 DjangoFilterBackend 。有关详细信息,请参阅documentation。 安装django-filter lib之后,不要忘记在settings.py文件中添加 DjangoFilterBackend

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

然后在视图中使用它:

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

过滤对象的替代方法是使用Filtering against query parameters。为此,只需覆盖get_queryset方法:

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