django queryset上的多个过滤器选项

时间:2018-06-21 18:27:52

标签: python django python-3.x django-rest-framework

对于Django REST api,我们有2种方法想法,我们正在尝试考虑。

目前,我们已经实现了1个过滤器选项:

class APINewsViewSet(viewsets.ModelViewSet):
    serializer_class = APINewsSerialiser

    def get_queryset(self):
        queryset = NewsBackup.objects.all()
        source = self.request.query_params.get('source', None)
        if source is not None:
            queryset = queryset.filter(news_source = source)
        return queryset

这可以达到:127.0.0.1/news?source=xxx

我们要做的其他事情是提供用户可以键入的其他过滤器选项,例如127.0.0.1/news?source=xxx&sourcename=xxx,然后这些过滤器选项将返回JSON对象,该对象仅包含source_id为xx和source_name为xx的数据

使用Django REST框架有可能吗?我们尝试在方法中添加其他选项:

query_params.get()

1 个答案:

答案 0 :(得分:1)

您可以将过滤器放在字典中,然后将字典用作过滤器。更好的是,您可以创建有效的过滤器来保护无效的过滤器。如下所示:

# {'queryparam': 'db_field'}
valid_filters = {
    'source': 'news_source',
    'source_name': 'source_name',
}

filters = {valid_filters[key]: value for key, value in self.request.query_params.items() if key in valid_filters.keys()}

# So if the query_params is like this: source=xxx&source_name=xxx
# filters value will look something like below:
{
    'news_source': 'xxx',
    'source_name': 'xxx',
}
# **filters transforms the filters to: (news_source='xxx', source_name='xxx')
queryset = queryset.filter(**filters)

或者,如果您不想对其进行大量自定义,则可以使用Django Filter之类的第三方程序包

更新 如果要获取多个值,例如:id=1&id=2,则可以使用getlist

ids = self.request.query_params.getlist('id')
# ids will have the list of id
# ids = [1, 2]
# you can then query the id
queryset = queryset.filter(id__in=ids)

更新2 如果要支持多个过滤器,可以再次创建字典:

keys = [
    'id',
    'source_name',
]
filters = {}
for key in keys:
    filter = query_params.getlist(key)
    if filter:
        filters['{}__in'.format(key)] = filter

queryset = queryset.filter(**filters)

您可以根据需要添加验证。