📌  相关文章
📜  在 Django Rest Framework 中过滤数据

📅  最后修改于: 2022-05-13 01:55:01.985000             🧑  作者: Mango

在 Django Rest Framework 中过滤数据

默认情况下,Django REST Framework 的通用列表视图返回模型管理器的整个查询集。对于现实世界的应用程序,需要根据需要过滤查询集以检索相关结果。因此,让我们讨论如何创建一个提供过滤功能的 RESTful Web 服务。

  • Django过滤器后端
  • 搜索过滤器
  • 排序过滤器

注意:您可以参考文章中使用的模型、序列化程序和项目视图的可浏览 API 部分

Django过滤器后端

DjangoFilterBackend 类用于根据指定的字段集过滤查询集。这个后端类为给定的字段自动创建一个 FilterSet ( django_filters.rest_framework.FilterSet ) 类。我们还可以使用自定义设置创建我们自己的 FilterSet 类。

要在我们的 Django Web 服务中配置过滤器后端类,我们需要在我们的虚拟环境中安装django-filter包。确保退出 Django 开发服务器(Ctrl + C)并激活虚拟环境。让我们运行下面的命令。

pip install django-filter

安装后,我们需要在settings.py文件中将django_filters应用定义为INSTALLED_APPS



Python3
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Django REST framework
    'rest_framework',
    'robots.apps.RobotsConfig',
    # Django Filters
    'django_filters',
]


Python3
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}


Python3
class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
      
    filter_fields = (
        'robot_category',
        'manufacturer',
    )


Python3
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
    ),
}


Python3
class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
      
    search_fields = (
        '^name',
    )


Python3
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.OrderingFilter',
    ),
}


Python3
class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
  
    ordering_fields = (
        'price',
    )


下一步,我们需要将 django_filters 中的DjangoFilterBackend类设置为默认过滤器类。让我们在 settings.py 文件中的REST_FRAMEWORK字典中提及它。

蟒蛇3

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}

现在我们的 RESTful Web 服务配置为使用django_filters.rest_framework.DjangoFilterBackend类提供的过滤功能。让我们过滤检索机器人列表的机器人类。 RobotList 类如下:

蟒蛇3

class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
      
    filter_fields = (
        'robot_category',
        'manufacturer',
    )

在这里,您可以注意到名为filter_fileds的属性,我们在其中指定要过滤的字段名称。现在,我们可以根据机器人的类别 (robot_category) 和/或制造商检索机器人。

让我们根据机器人类别过滤机器人。 HTTPie 命令是

输出:

让我们尝试另一个基于机器人类别和制造商过滤机器人的 HTTPie 命令。 HTTPie 命令是

输出:

现在让我们检查 Browsable API 中的功能。您可以浏览以下网址

您可以单击右上角的过滤器按钮来使用过滤器功能。会显示如下图



单击提交按钮后,您将获得基于填充的过滤器字段的结果,如下所示。

搜索过滤器

SearchFilter类支持基于单个查询参数的搜索功能,它基于 Django 管理员的搜索函数。

默认情况下, SearchFilter类使用不区分大小写的部分匹配,并且它可能包含多个搜索词(应该是空格和/或逗号分隔)。我们还可以通过在 search_fields 前面添加各种字符来限制搜索行为。

  • '^' 以搜索开头。
  • '=' 完全匹配。
  • '@' 全文搜索。 (用于 Django 的 PostgreSQL 后端)
  • '$' 正则搜索

默认情况下,搜索参数名为search,您可以使用SEARCH_PARAM设置覆盖它。让我们通过将rest_framework.filters.SearchFilter类添加到REST_FRAMEWORK字典来使用 SearchFilter 类。

蟒蛇3

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
    ),
}

我们的 RobotList 类如下所示:

蟒蛇3

class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
      
    search_fields = (
        '^name',
    )

search_fields属性指定了一个字符串元组,它表示我们想要包含在搜索功能中的字段名称。



让我们搜索以名称“IRB”开头的机器人。 HTTPie 命令是

输出:

排序过滤器

OrderingFilter类允许您根据指定的字段对结果进行排序。默认情况下,查询参数命名为ordering,它可以被ORDERING_PARAM设置覆盖。 ordering_field属性指定一个字符串元组,它指示对结果进行排序的字段名称。

如果您没有在视图上指定ordering_fields属性,过滤器类允许用户过滤由 serializer_class 属性指定的任何可读字段。这允许用户针对密码哈希字段等敏感信息进行排序,这可能导致意外的数据泄漏。您还可以通过在视图上设置排序属性来指定默认顺序。它可以是一个字符串或字符串列表/元组。

要使用OrderingFilter类,我们需要将该类设置为REST_FRAMEWORK字典的默认排序过滤器类。

蟒蛇3

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS'🙁
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.OrderingFilter',
    ),
}

让我们提一下 RobotList 类上的 ordering_fields 属性。代码如下:

蟒蛇3

class RobotList(generics.ListCreateAPIView):
    queryset = Robot.objects.all()
    serializer_class = RobotSerializer
    name = 'robot-list'
  
    ordering_fields = (
        'price',
    )

现在,让我们根据价格订单的增加检索机器人。 HTTPie 命令是

输出: