如何在Django REST Framework中实现过滤功能与Basic基础认证
你当前使用了DRF的函数式视图,filter_backends、filterset_fields、authentication_classes、permission_classes均为DRF类视图的专属配置属性,直接写在函数视图中不会生效,按以下步骤调整即可实现需求。
前置配置
首先确保你已经完成基础依赖配置,在项目settings.py中添加如下内容:
INSTALLED_APPS = [ # 原有其他应用 'django_filters', ] # 全局过滤配置,也可以后续在视图中单独指定 REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] }
实现方案一:改用类视图(推荐)
类视图原生支持DRF的过滤、认证等扩展配置,代码更简洁易维护。
修改views.py代码:
from requests import api from rest_framework import status, generics from rest_framework.response import Response from rest_framework.filters import SearchFilter from rest_framework.authentication import BasicAuthentication from rest_framework.permissions import IsAuthenticated from django_filters.rest_framework import DjangoFilterBackend from hello.models import Robot,jenkinsHistory from hello.api.serializers import RobotSerializer, jenkinsHistorySerializer # Robot列表视图 class RobotListApiView(generics.ListCreateAPIView): queryset = Robot.objects.all() serializer_class = RobotSerializer # 过滤配置,支持按robot和id过滤 filter_backends = [DjangoFilterBackend] filterset_fields = ['robot', 'id'] # 基础认证配置 authentication_classes = [BasicAuthentication] permission_classes = [IsAuthenticated] # 构建历史视图 class RobotHistoryApiView(generics.ListCreateAPIView): queryset = jenkinsHistory.objects.all() serializer_class = jenkinsHistorySerializer # 过滤配置,支持按id、关联的robot名称过滤 filter_backends = [DjangoFilterBackend] filterset_fields = ['id', 'jenkinsJobName__robot'] # 基础认证配置 authentication_classes = [BasicAuthentication] permission_classes = [IsAuthenticated]
再修改项目路由配置urls.py,将原有函数视图的路由替换为类视图:
# 导入上面的类视图 from hello.api.views import RobotListApiView, RobotHistoryApiView urlpatterns = [ # 原有其他路由 path('robots/', RobotListApiView.as_view(), name='robot-list'), path('history/', RobotHistoryApiView.as_view(), name='robot-history'), ]
配置完成后即可使用以下过滤规则:
- 访问
/robots/?robot=Demo查询名称为Demo的机器人 - 访问
/robots/?id=1查询id为1的机器人 - 访问
/history/?jenkinsJobName__robot=Demo查询Demo机器人的构建历史 - 访问
/history/?id=1查询id为1的构建记录
所有接口均需要输入Django后台的用户名密码进行基础认证后才能访问。
实现方案二:保留函数式视图
如果要保留现有函数视图写法,手动处理过滤逻辑,同时使用装饰器添加认证配置即可。
修改views.py代码:
from requests import api from rest_framework import status from rest_framework.decorators import api_view, authentication_classes, permission_classes from rest_framework.response import Response from rest_framework.authentication import BasicAuthentication from rest_framework.permissions import IsAuthenticated from hello.models import Robot,jenkinsHistory from hello.api.serializers import RobotSerializer, jenkinsHistorySerializer @api_view(["GET", "POST"]) @authentication_classes([BasicAuthentication]) @permission_classes([IsAuthenticated]) def robot_list_api_view(request): if request.method == "GET": rb = Robot.objects.all() # 手动处理查询参数实现过滤 robot = request.query_params.get('robot') id = request.query_params.get('id') if robot: rb = rb.filter(robot=robot) if id: rb = rb.filter(id=id) serializer = RobotSerializer(rb, many=True) return Response(serializer.data) elif request.method == "POST": return Response("You can do anything here") @api_view(["GET", "POST"]) @authentication_classes([BasicAuthentication]) @permission_classes([IsAuthenticated]) def robot_history_api_view(request): if request.method == "GET": rh = jenkinsHistory.objects.all() # 手动处理查询参数实现过滤 robot_name = request.query_params.get('robot') id = request.query_params.get('id') if robot_name: rh = rh.filter(jenkinsJobName__robot=robot_name) if id: rh = rh.filter(id=id) serializer = jenkinsHistorySerializer(rh, many=True) return Response(serializer.data) elif request.method == "POST": return Response("You can do anything here")
该方案无需修改路由,原有路由可以直接复用,过滤规则和认证规则和类视图方案一致。
验证说明
基础认证需要你提前创建Django后台用户,测试时可以在请求头中携带认证信息,或者使用Postman等工具在Authorization模块选择Basic Auth,输入对应的用户名密码即可。
内容的提问来源于stack exchange,提问作者Rituparna Das
相关产品推荐
相关产品推荐

