如何让Django Rest Framework适配vue-bootstrap4-table查询参数格式?
解决方案:让Django Rest Framework适配vue-bootstrap4-table的查询参数格式
当然可行!我们只需要在DRF中添加一层参数转换逻辑,把vue-bootstrap4-table传来的queryParams解析成DRF能识别的过滤、排序格式即可。下面是具体的实现步骤和代码示例:
1. 自定义FilterBackend处理参数转换
创建一个自定义的过滤器后端,专门负责解析前端传来的JSON格式参数,并转换成DRF兼容的查询条件:
from rest_framework.filters import BaseFilterBackend import json class VueBootstrapTableFilterBackend(BaseFilterBackend): def filter_queryset(self, request, queryset, view): # 提取前端传来的queryParams参数 query_params_str = request.query_params.get('queryParams') if not query_params_str: return queryset # 解析JSON字符串,处理解析失败的情况 try: query_params = json.loads(query_params_str) except json.JSONDecodeError: return queryset # 处理筛选条件:转换为DRF的字段__操作符格式 filter_kwargs = {} for filter_item in query_params.get('filters', []): filter_type = filter_item.get('type') field_name = filter_item.get('name') filter_value = filter_item.get('text') # 这里以simple类型为例,对应icontains模糊匹配,可根据需求扩展 if filter_type == 'simple' and field_name and filter_value: filter_kwargs[f"{field_name}__icontains"] = filter_value # 可以添加更多类型的处理,比如range、date等 # elif filter_type == 'range': # filter_kwargs[f"{field_name}__gte"] = filter_value.get('start') # filter_kwargs[f"{field_name}__lte"] = filter_value.get('end') # 应用筛选条件到查询集 queryset = queryset.filter(**filter_kwargs) # 处理排序:前端的sort数组格式和DRF原生排序兼容,直接复用 sort_fields = query_params.get('sort', []) if sort_fields: queryset = queryset.order_by(*sort_fields) return queryset
2. 在ViewSet中配置自定义过滤器和分页
修改你的ProductViewSet,替换或添加自定义的过滤器后端,并配置分页类以支持前端的per_page参数:
from rest_framework import viewsets, filters from rest_framework.pagination import PageNumberPagination from .models import Product from .serializers import ProductSerializer from .filters import VueBootstrapTableFilterBackend # 假设上面的类放在filters.py中 # 自定义分页类,适配前端的per_page参数 class CustomPagination(PageNumberPagination): page_size_query_param = 'per_page' class ProductViewSet(viewsets.ModelViewSet): serializer_class = ProductSerializer queryset = Product.objects.all() # 使用自定义过滤器后端,保留OrderingFilter作为补充(可选) filter_backends = [VueBootstrapTableFilterBackend, filters.OrderingFilter] ordering_fields = '__all__' # 配置自定义分页 pagination_class = CustomPagination
关键说明
- 参数解析:前端传来的
queryParams是URL编码后的JSON字符串,我们需要先解码并解析成Python字典,再逐一处理筛选、排序参数。 - 筛选转换:根据前端的
filter type(比如simple),映射到DRF对应的查询操作符(比如__icontains),你可以根据业务需求扩展更多类型的转换逻辑。 - 排序兼容:vue-bootstrap4-table的排序格式(升序为字段名,降序为
-字段名)和DRF原生的排序格式完全一致,所以可以直接复用。 - 分页适配:通过自定义
PageNumberPagination,把分页大小的参数名改为per_page,和前端的参数保持一致。
如果之前的ProductFilter是基于django-filter定义的,你可以选择保留并调整逻辑(比如把转换后的filter_kwargs传给过滤器),或者直接用上面的自定义逻辑替代,根据你的实际需求决定。
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

